diff --git a/.gitignore b/.gitignore index 603b140773..8383495b16 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /.idea/workspace.xml /.idea/navEditor.xml /.idea/assetWizardSettings.xml +.idea .DS_Store /build /captures diff --git a/.idea/gradle.xml b/.idea/gradle.xml index d291b3d7cd..db9382e9a6 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,15 +1,58 @@ + diff --git a/.idea/misc.xml b/.idea/misc.xml index af0bbdde16..cd77a1f062 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,14 +1,10 @@ - - - - + + + - + - - \ No newline at end of file diff --git a/app/README.md b/app/README.md new file mode 100644 index 0000000000..bbf8c992fb --- /dev/null +++ b/app/README.md @@ -0,0 +1,35 @@ +# APP 壳 + +## 加载模块 + +## 初始化部分服务 + +## 定义 flavor + +### basic 维度 + +产品形态:区别 applicationId,定义服务加载 + +1. independent:独立app,作为普通 app 运行在系统 +2. launcher:作为 launcher 运行在系统 + +### product 维度 + +产品线,各个产品线引入不同服务,实现不同服务内容 + +1. f8xx: 分体机 - launcher +2. e8xx: E系列m4(2+32) - launcher +3. em4: E系列m4(2+32) - launcher +4. em3: E系列m3(2+32) - independent +5. em1: E系列m1(1+16) - independent +6. d8xx: D系列(2+32) - independent +7. d82x: D系列(1+16) - independent +8. byd: 比亚迪应用市场 - independent + +### env 维度 + +1. online: 线上环境 +2. qa: 测试环境 +3. demo: 演示环境(大部分时候都是测试环境) + +## 区分 flavor 功能引入 diff --git a/app/build.gradle b/app/build.gradle index f266ec223b..eaaa292644 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,29 +1,369 @@ apply plugin: 'com.android.application' +apply plugin: 'com.alibaba.arouter' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' +import java.text.SimpleDateFormat android { compileSdkVersion rootProject.ext.android.compileSdkVersion - buildToolsVersion rootProject.ext.android.buildToolsVersion + // buildToolsVersion rootProject.ext.android.buildToolsVersion defaultConfig { - applicationId rootProject.ext.android.applicationId minSdkVersion rootProject.ext.android.minSdkVersion targetSdkVersion rootProject.ext.android.targetSdkVersion - versionCode rootProject.ext.android.versionCode - versionName rootProject.ext.android.versionName + versionCode rootProject.versionCode as int + versionName rootProject.versionName + applicationId rootProject.ext.android.applicationId testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + javaCompileOptions { + annotationProcessorOptions { + arguments = [AROUTER_MODULE_NAME: project.getName()] + } + } + + multiDexEnabled true + externalNativeBuild { + ndk { + // 设置支持的SO库架构 + abiFilters "armeabi-v7a" + } + } + } + signingConfigs { + release { + keyAlias = 'CarLauncher' + storeFile file('../keystore/car_launcher.jks') + storePassword 'ZDauto123456' + keyPassword 'ZDauto123456' + } } buildTypes { + debug { + debuggable = true + minifyEnabled false + signingConfig signingConfigs.release + } release { minifyEnabled false + zipAlignEnabled false + shrinkResources false + signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + compileOptions { + sourceCompatibility 1.8 + targetCompatibility 1.8 + } + + sourceSets { + main { + manifest.srcFile 'src/main/AndroidManifest.xml' + } + launcher { + manifest.srcFile 'src/launcher/AndroidManifest.xml' + } + independent { + manifest.srcFile 'src/independent/AndroidManifest.xml' + } + e8xx{ + manifest.srcFile 'src/e8xx/AndroidManifest.xml' + } + em4 { + manifest.srcFile 'src/em4/AndroidManifest.xml' + } + } + + flavorDimensions "product", "basic", "env" + + productFlavors { + //独立app + independent{ + dimension "basic" + applicationId rootProject.ext.android.independentApplicationId + // 是否启动位置服务 + buildConfigField 'boolean', 'LAUNCH_LOCATION_SERVICE', 'false' + // 是否使用高德sdk自定义导航 + buildConfigField 'boolean', 'USE_CUSTOM_NAVI', 'true' + // 是否作为 launcher 运行 + buildConfigField 'boolean', 'IS_LAUNCHER', 'false' + buildConfigField 'String', 'SOCKET_APP_ID', '\"com.mogo.launcher\"' + } + // launcher app + launcher{ + dimension "basic" + applicationId rootProject.ext.android.launcherApplicationId + // 是否启动位置服务 + buildConfigField 'boolean', 'LAUNCH_LOCATION_SERVICE', 'true' + // 是否使用高德sdk自定义导航 + buildConfigField 'boolean', 'USE_CUSTOM_NAVI', 'true' + // 是否作为 launcher 运行 + buildConfigField 'boolean', 'IS_LAUNCHER', 'true' + buildConfigField 'String', 'SOCKET_APP_ID', '\"com.mogo.launcher\"' + } + // f系列-分体机全系列,未细分 + f8xx{ + dimension "product" + // 使用思必驰语音 + buildConfigField 'int', 'AIType','2' + buildConfigField 'boolean', 'AI_ASSIST_ACTIVE_STAUTS', 'false' + // 车机类型,主要用于区分自研车机还是别人家的车机,自研车机类型为0 + buildConfigField 'int', 'CAR_MACHINE_TYPE', '0' + } + // e系列,采用Launcher方案 + e8xx { + dimension "product" + // 使用思必驰语音 + buildConfigField 'int', 'AIType','2' + buildConfigField 'boolean', 'AI_ASSIST_ACTIVE_STAUTS', 'true' + // 车机类型,主要用于区分自研车机还是别人家的车机,自研车机类型为0 + buildConfigField 'int', 'CAR_MACHINE_TYPE', '0' + } + // 同上 + em4 { + dimension "product" + // 使用思必驰语音 + buildConfigField 'int', 'AIType','2' + buildConfigField 'boolean', 'AI_ASSIST_ACTIVE_STAUTS', 'true' + // 车机类型,主要用于区分自研车机还是别人家的车机,自研车机类型为0 + buildConfigField 'int', 'CAR_MACHINE_TYPE', '0' + } + // e系列-2+32,对标D系列2+32,采用独立app的形式 + em3 { + dimension "product" + // 使用思必驰语音 + buildConfigField 'int', 'AIType', '2' + buildConfigField 'boolean', 'AI_ASSIST_ACTIVE_STAUTS', 'true' + // 车机类型,主要用于区分自研车机还是别人家的车机,自研车机类型为0 + buildConfigField 'int', 'CAR_MACHINE_TYPE', '0' + } + // e系列-1+16,对标D系列1+16,采用独立app形式 + em1 { + dimension "product" + // 使用思必驰语音 + buildConfigField 'int', 'AIType', '2' + buildConfigField 'boolean', 'AI_ASSIST_ACTIVE_STAUTS', 'true' + // 车机类型,主要用于区分自研车机还是别人家的车机,自研车机类型为0 + buildConfigField 'int', 'CAR_MACHINE_TYPE', '0' + } + // d系列 + d8xx { + dimension "product" + // 使用同行者语音 + buildConfigField 'int', 'AIType','1' + buildConfigField 'boolean', 'AI_ASSIST_ACTIVE_STAUTS', 'true' + // 车机类型,主要用于区分自研车机还是别人家的车机,自研车机类型为0 + buildConfigField 'int', 'CAR_MACHINE_TYPE', '0' + } + // d系列 1+16 版本 + d82x{ + dimension "product" + // 使用同行者语音 + buildConfigField 'int', 'AIType','1' + buildConfigField 'boolean', 'AI_ASSIST_ACTIVE_STAUTS', 'true' + // 车机类型,主要用于区分自研车机还是别人家的车机,自研车机类型为0 + buildConfigField 'int', 'CAR_MACHINE_TYPE', '0' + } + // 比亚迪 + bydauto{ + dimension "product" + // 不使用语音 + buildConfigField 'int', 'AIType','0' + buildConfigField 'boolean', 'AI_ASSIST_ACTIVE_STAUTS', 'false' + // 车机类型,主要用于区分自研车机还是别人家的车机,其他车机,比亚迪定为1 + buildConfigField 'int', 'CAR_MACHINE_TYPE', '1' + } + qa { + dimension "env" + buildConfigField 'int', 'NET_ENV', '2' + } + online { + dimension "env" + buildConfigField 'int', 'NET_ENV', '3' + } + demo { + dimension "env" + buildConfigField 'int', 'NET_ENV', '4' + } + } + + packagingOptions { + exclude 'META-INF/io.netty.versions.properties' + } +} + +def generateVersionCode() { + String vn = rootProject.ext.android.versionName + String[] versions = vn.split("\\.") + if (versions.length == 3) { + int num1 = Integer.valueOf(versions[0]) + int num2 = Integer.valueOf(versions[1]) + int num3 = Integer.valueOf(versions[2]) + if (num1 < 1 || num1 > 99){ + throw new GradleException("版本号必须定义为 x.y.z,x[1,99], y[0, 99], z[0, 99])") + } + if (num2 < 0 || num2 > 99){ + throw new GradleException("版本号必须定义为 x.y.z,x[1,99], y[0, 99], z[0, 99])") + } + if (num3 < 0 || num3 > 99){ + throw new GradleException("版本号必须定义为 x.y.z,x[1,99], y[0, 99], z[0, 99])") + } + StringBuilder builder = new StringBuilder() + builder.append(num1) + if( num2 > 9 ){ + builder.append(num2) + } else { + builder.append("0").append(num2) + } + if( num3 > 9 ){ + builder.append(num3) + } else { + builder.append("0").append(num3) + } + println("last versionCode ${builder}") + return Integer.valueOf(builder.toString()) + } else { + throw new GradleException("版本号必须定义为 x.y.z,x[1,99], y[0, 99], z[0, 99])") + } + +} + +repositories { + flatDir { + dirs 'libs' + } } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) + + //Crash日志收集 + implementation rootProject.ext.dependencies.crashSdk implementation rootProject.ext.dependencies.androidxappcompat - implementation rootProject.ext.dependencies.androidxconstraintlayout - testImplementation rootProject.ext.dependencies.junit - androidTestImplementation rootProject.ext.dependencies.androidxjunit - androidTestImplementation rootProject.ext.dependencies.androidxespressocore + implementation rootProject.ext.dependencies.arouter + implementation rootProject.ext.dependencies.boostmultidex + debugImplementation rootProject.ext.dependencies.leakcanary + testImplementation rootProject.ext.dependencies.leakcanary + releaseImplementation rootProject.ext.dependencies.leakcanarynoop + + implementation rootProject.ext.dependencies.carcallprovider + implementation rootProject.ext.dependencies.carcall + implementation rootProject.ext.dependencies.moduletanlu, { + exclude group: 'com.mogo.module', module: 'module-share' + } + + if (Boolean.valueOf(RELEASE)) { + launcherImplementation rootProject.ext.dependencies.modulemainlauncher + independentImplementation rootProject.ext.dependencies.modulemainindependent + implementation rootProject.ext.dependencies.mogocommons + implementation rootProject.ext.dependencies.modulecommon + implementation rootProject.ext.dependencies.modulesearch + implementation rootProject.ext.dependencies.mogomoduleguide + implementation rootProject.ext.dependencies.mogomoduleauth + implementation rootProject.ext.dependencies.modulemedia + implementation rootProject.ext.dependencies.moduleservice + implementation rootProject.ext.dependencies.modulesplash + implementation rootProject.ext.dependencies.moduleV2x + } else { + launcherImplementation project(':main-extensions:mogo-module-main-launcher') + independentImplementation project(':main-extensions:mogo-module-main-independent') + implementation project(':foudations:mogo-commons') + implementation project(':modules:mogo-module-common') + implementation project(':modules:mogo-module-search') + implementation project(':modules:mogo-module-authorize') + implementation project(':modules:mogo-module-media') + implementation project(':modules:mogo-module-service') + implementation project(':modules:mogo-module-splash') + implementation project(':modules:mogo-module-v2x') + } + + apply from: "./functions/baseservices.gradle" + apply from: "./functions/socketpush.gradle" + apply from: "./functions/gpssimulator.gradle" + apply from: "./functions/eventpanel.gradle" + apply from: "./functions/leftpanel.gradle" +} + +//android.applicationVariants.all { variant -> +// variant.outputs.all { //这里修改apk文件名 +// outputFileName = "Launcher2.0_V${android.defaultConfig.versionName}_${getCurrentDate()}_${variant.name}_${getGitCommit()}.apk" +// println outputFileName +// } +//} + +android.applicationVariants.all { variant -> + def buildTime = new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+08:00")) + def flavor = variant.productFlavors.collect { it.name }.join('-') + + variant.outputs.all { output -> + outputFileName = [ + rootProject.applicationName, + "v${variant.versionName}", + buildTime, + flavor.length() > 0 ? "[${flavor}]" : "", + variant.buildType.name + ].findAll { it.length() > 0 }.join('_') << ".apk" + } +} + + +def getMonthAndDay() { + + SimpleDateFormat sdf = new SimpleDateFormat("MMddHH") + return sdf.format(new Date()) +} + +def getCurrentDate() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss") + return sdf.format(new Date()) +} + +def getGitCommit() { + def gitDir = new File("${new File("${rootDir}")}/.git") + if (!gitDir.isDirectory()) { + return 'non_git_build' + } + + def cmd = 'git log --pretty=format:%h -1' + def gitCommit = cmd.execute().text.trim() + + print gitCommit + + def cmd2 = 'git status -s' + def gitStatus = cmd2.execute().text.trim() + + println '---------' + + print gitStatus + if (gitStatus != null && !gitStatus.isEmpty()) { + return 'local-build' + } + + assert !gitCommit.isEmpty() + gitCommit +} + +afterEvaluate { + + it.getTasks().iterator().forEachRemaining { + def nameLowCase = it.name + + if (nameLowCase.startsWith("assemble") + && nameLowCase.contains("Independent") + && (nameLowCase.endsWith("Debug") || nameLowCase.endsWith("Release"))) { + it.group = "assembleIndependent" + } else if (nameLowCase.startsWith("assemble") + && nameLowCase.contains("Launcher") + && (nameLowCase.endsWith("Debug") || nameLowCase.endsWith("Release"))) { + it.group = "assembleLauncher" + } else if (nameLowCase.startsWith("install") + && nameLowCase.contains("Independent") + && (nameLowCase.endsWith("Debug") || nameLowCase.endsWith("Release"))) { + it.group = "installIndependent" + } else if (nameLowCase.startsWith("install") + && nameLowCase.contains("Launcher") + && (nameLowCase.endsWith("Debug") || nameLowCase.endsWith("Release"))) { + it.group = "installLauncher" + } + } } diff --git a/app/functions/README.md b/app/functions/README.md new file mode 100644 index 0000000000..27064aa5d3 --- /dev/null +++ b/app/functions/README.md @@ -0,0 +1 @@ +# 不同渠道,依赖的实现不一样,需要各个渠道都去依赖各自需要的实现,渠道太多导致build.gradle 文件臃肿,可以通过分gradle文件方式减少臃肿 \ No newline at end of file diff --git a/app/functions/baseservices.gradle b/app/functions/baseservices.gradle new file mode 100644 index 0000000000..0372c05860 --- /dev/null +++ b/app/functions/baseservices.gradle @@ -0,0 +1,26 @@ +// 基础服务:仅比亚迪渠道用sdk方式实现,其他都基于apk基础服务 + +project.dependencies { + if (Boolean.valueOf(RELEASE)) { + bydautoImplementation rootProject.ext.dependencies.mogobaseservicesdk + + d82xImplementation rootProject.ext.dependencies.mogobaseserviceapk + em1Implementation rootProject.ext.dependencies.mogobaseserviceapk + d8xxImplementation rootProject.ext.dependencies.mogobaseserviceapk + em4Implementation rootProject.ext.dependencies.mogobaseserviceapk + e8xxImplementation rootProject.ext.dependencies.mogobaseserviceapk + e8xxImplementation rootProject.ext.dependencies.mogobaseserviceapk + f8xxImplementation rootProject.ext.dependencies.mogobaseserviceapk + em3Implementation rootProject.ext.dependencies.mogobaseserviceapk + } else { + bydautoImplementation project(':foudations:mogo-base-services-sdk') + + d82xImplementation project(':foudations:mogo-base-services-apk') + em1Implementation project(':foudations:mogo-base-services-apk') + d8xxImplementation project(':foudations:mogo-base-services-apk') + em4Implementation project(':foudations:mogo-base-services-apk') + e8xxImplementation project(':foudations:mogo-base-services-apk') + f8xxImplementation project(':foudations:mogo-base-services-apk') + em3Implementation project(':foudations:mogo-base-services-apk') + } +} \ No newline at end of file diff --git a/app/functions/eventpanel.gradle b/app/functions/eventpanel.gradle new file mode 100644 index 0000000000..af40aafa69 --- /dev/null +++ b/app/functions/eventpanel.gradle @@ -0,0 +1,25 @@ +// 道路事件操作面板 + +project.dependencies { + if (Boolean.valueOf(RELEASE)) { + d82xImplementation rootProject.ext.dependencies.moduleventpanelnoop + em1Implementation rootProject.ext.dependencies.moduleventpanelnoop + bydautoImplementation rootProject.ext.dependencies.moduleventpanelnoop + + d8xxImplementation rootProject.ext.dependencies.moduleventpanel + em4Implementation rootProject.ext.dependencies.moduleventpanel + e8xxImplementation rootProject.ext.dependencies.moduleventpanel + f8xxImplementation rootProject.ext.dependencies.moduleventpanel + em3Implementation rootProject.ext.dependencies.moduleventpanel + } else { + d82xImplementation project(':modules:mogo-module-event-panel-noop') + em1Implementation project(':modules:mogo-module-event-panel-noop') + bydautoImplementation project(':modules:mogo-module-event-panel-noop') + + d8xxImplementation project(':modules:mogo-module-event-panel') + em4Implementation project(':modules:mogo-module-event-panel') + e8xxImplementation project(':modules:mogo-module-event-panel') + f8xxImplementation project(':modules:mogo-module-event-panel') + em3Implementation project(':modules:mogo-module-event-panel') + } +} \ No newline at end of file diff --git a/app/functions/gpssimulator.gradle b/app/functions/gpssimulator.gradle new file mode 100644 index 0000000000..c33febbc07 --- /dev/null +++ b/app/functions/gpssimulator.gradle @@ -0,0 +1,11 @@ +// 基于后台轨迹模拟的gps模拟服务 + +project.dependencies { + if (Boolean.valueOf(RELEASE)) { + debugImplementation rootProject.ext.dependencies.gpssimulatordebug + releaseImplementation rootProject.ext.dependencies.gpssimulatornoop + } else { + debugImplementation project(':modules:mogo-module-gps-simulator-debug') + releaseImplementation project(':modules:mogo-module-gps-simulator-noop') + } +} \ No newline at end of file diff --git a/app/functions/leftpanel.gradle b/app/functions/leftpanel.gradle new file mode 100644 index 0000000000..9af57c4e47 --- /dev/null +++ b/app/functions/leftpanel.gradle @@ -0,0 +1,26 @@ +// 辅助驾驶占位模块,目前部分车机不上辅助驾驶功能,使用该模块能力代替 + +project.dependencies { + if (Boolean.valueOf(RELEASE)) { + d82xImplementation rootProject.ext.dependencies.moduleleftpanel + em1Implementation rootProject.ext.dependencies.moduleleftpanel + bydautoImplementation rootProject.ext.dependencies.moduleleftpanel + + d8xxImplementation rootProject.ext.dependencies.moduleleftpanelnoop + em4Implementation rootProject.ext.dependencies.moduleleftpanelnoop + e8xxImplementation rootProject.ext.dependencies.moduleleftpanelnoop + e8xxImplementation rootProject.ext.dependencies.moduleleftpanelnoop + f8xxImplementation rootProject.ext.dependencies.moduleleftpanelnoop + em3Implementation rootProject.ext.dependencies.moduleleftpanelnoop + } else { + d82xImplementation project(':modules:mogo-module-left-panel') + em1Implementation project(':modules:mogo-module-left-panel') + bydautoImplementation project(':modules:mogo-module-left-panel') + + d8xxImplementation project(':modules:mogo-module-left-panel-noop') + em4Implementation project(':modules:mogo-module-left-panel-noop') + e8xxImplementation project(':modules:mogo-module-left-panel-noop') + f8xxImplementation project(':modules:mogo-module-left-panel-noop') + em3Implementation project(':modules:mogo-module-left-panel-noop') + } +} \ No newline at end of file diff --git a/app/functions/socketpush.gradle b/app/functions/socketpush.gradle new file mode 100644 index 0000000000..ef9923abfd --- /dev/null +++ b/app/functions/socketpush.gradle @@ -0,0 +1,7 @@ +// 基于socket长链的push推送 + +project.dependencies { + implementation rootProject.ext.dependencies.modulepushbase + launcherImplementation rootProject.ext.dependencies.modulepush + independentImplementation rootProject.ext.dependencies.modulepushnoop +} \ No newline at end of file diff --git a/app/libs/persistentlib.jar b/app/libs/persistentlib.jar new file mode 100644 index 0000000000..7a6ce17de1 Binary files /dev/null and b/app/libs/persistentlib.jar differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index f1b424510d..3f451d8bed 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -19,3 +19,355 @@ # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile + + +# +#-------------------------------------------基本不用动区域---------------------------------------------- +# +# +# -----------------------------基本 ----------------------------- + +# 指定代码的压缩级别 0 - 7(指定代码进行迭代优化的次数,在Android里面默认是5,这条指令也只有在可以优化时起作用。) +-optimizationpasses 5 +# 混淆时不会产生形形色色的类名(混淆时不使用大小写混合类名) +-dontusemixedcaseclassnames +# 指定不去忽略非公共的库类(不跳过library中的非public的类) +-dontskipnonpubliclibraryclasses +# 指定不去忽略包可见的库类的成员 +-dontskipnonpubliclibraryclassmembers +#不进行优化,建议使用此选项, +-dontoptimize + # 不进行预校验,Android不需要,可加快混淆速度。 +-dontpreverify + +# 屏蔽警告,暂不开启。用于抛出异常 +#-ignorewarnings +# 指定混淆是采用的算法,后面的参数是一个过滤器 +# 这个过滤器是谷歌推荐的算法,一般不做更改 +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* +# 保护代码中的Annotation不被混淆 +-keepattributes *Annotation*,InnerClasses,Signature,EnclosingMethod +# 避免混淆泛型, 这在JSON实体映射时非常重要 +-keepattributes Signature +# 抛出异常时保留代码行号 +-keepattributes SourceFile,LineNumberTable + #优化时允许访问并修改有修饰符的类和类的成员,这可以提高优化步骤的结果。 +# 比如,当内联一个公共的getter方法时,这也可能需要外地公共访问。 +# 虽然java二进制规范不需要这个,要不然有的虚拟机处理这些代码会有问题。当有优化和使用-repackageclasses时才适用。 +#指示语:不能用这个指令处理库中的代码,因为有的类和类成员没有设计成public ,而在api中可能变成public +-allowaccessmodification + # 混淆时记录日志(打印混淆的详细信息) + # 这句话能够使我们的项目混淆后产生映射文件 + # 包含有类名->混淆后类名的映射关系 +-verbose + + +# +# ----------------------------- 默认保留 ----------------------------- +# +#---------------------------------------------------- +# 保持哪些类不被混淆 +#继承activity,application,service,broadcastReceiver,contentprovider....不进行混淆 + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Fragment +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class * extends android.view.View + +-keep public class androidx.*{*;} +-keep public class * extends androidx.*{*;} +-keep interface androidx.* {*;} +-dontwarn androidx.** + +-dontwarn android.support.design.** +-keep public class android.support.design.R$* { *; } +-keep class com.google.android.material.* {*;} + +-keepclasseswithmembernames class * { + native ; +} + +#这个主要是在layout 中写的onclick方法android:onclick="onClick",不进行混淆 +#表示不混淆Activity中参数是View的方法 +-keepclassmembers class * extends android.app.Activity{ + public void *(android.view.View); +} +#表示不混淆枚举中的values()和valueOf()方法 +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +#表示不混淆任何一个View中的setXxx()和getXxx()方法, +#因为属性动画需要有相应的setter和getter的方法实现,混淆了就无法工作了。 +-keep public class * extends android.view.View{ + *** get*(); + void set*(***); + public (android.content.Context); + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); +} +-keepclasseswithmembers class * { + public (android.content.Context, android.util.AttributeSet); + public (android.content.Context, android.util.AttributeSet, int); +} + +#表示不混淆Parcelable +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable *; +} + +# 这指定了继承Serizalizable的类的如下成员不被移除混淆 +-keepclassmembers class * implements java.io.Serializable { + static final long serialVersionUID; + private static final java.io.ObjectStreamField[] serialPersistentFields; + private void writeObject(java.io.ObjectOutputStream); + private void readObject(java.io.ObjectInputStream); + java.lang.Object writeReplace(); + java.lang.Object readResolve(); +} + +# 保留R下面的资源 +-keep class **.R$* { + *; +} + +#不混淆资源类下static的 +-keepclassmembers class **.R$* { + public static ; +} + +# 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆 +-keepclassmembers class * { + void *(**On*Event); + void *(**On*Listener); +} + +#(可选)避免Log打印输出 +-assumenosideeffects class android.util.Log { + public static *** v(...); + public static *** d(...); + public static *** i(...); + public static *** w(...); +} + +#kotlin +-keep class kotlin.* { *; } +-keepclassmembernames class kotlinx.*{ + volatile ; +} +-keep class kotlin.Metadata { *; } +-dontwarn kotlin.* +-dontwarn kotlin.** +-keepclassmembers class **$WhenMappings { + ; +} +-keepclassmembers class kotlin.Metadata { + public ; +} +-assumenosideeffects class kotlin.jvm.internal.Intrinsics { + static void checkParameterIsNotNull(java.lang.Object, java.lang.String); +} +-keepclassmembers class kotlin.Metadata { *; } +-keep @kotlin.Metadata class * +-keepclasseswithmembers @kotlin.Metadata class * { *; } + +-dontwarn android.telephony.TelephonyManager.** +-keep class android.telephony.TelephonyManager.**{*;} + +#----------------------------------------第三方库---------------------------------------------- +#-----高德地图----- + +#内置语音 V5.6.0之后 +-keep class com.alibaba.idst.nls.**{*;} +-keep class com.google.**{*;} +-keep class com.nlspeech.nlscodec.** {*;} +-keep public class com.alibaba.mit.alitts.*{*;} +-keep class com.alibaba.mit.alitts.** {*;} +-dontwarn com.alibaba.mit.alitts.ICallback + +#3D 地图 V5.0.0之后: +-keep class com.amap.api.maps.**{*;} +-keep class com.autonavi.**{*;} +-keep class com.amap.api.trace.**{*;} +#定位 +-keep class com.loc.** {*;} +-keep class com.amap.api.location.**{*;} +-keep class com.amap.api.fence.**{*;} +-keep class com.autonavi.aps.amapapi.model.**{*;} +#搜索 +-keep class com.amap.api.services.**{*;} +#导航 +-keep class com.amap.api.navi.**{*;} + + +#-----Gson----- +-dontwarn sun.misc.** +# Application classes that will be serialized/deserialized over Gson +-keep class com.google.gson.examples.android.model.** { ; } +# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory, +# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter) +-keep class * extends com.google.gson.TypeAdapter +-keep class * implements com.google.gson.TypeAdapterFactory +-keep class * implements com.google.gson.JsonSerializer +-keep class * implements com.google.gson.JsonDeserializer +# Prevent R8 from leaving Data object members always null +-keepclassmembers,allowobfuscation class * { + @com.google.gson.annotations.SerializedName ; +} + +#-----ARouter----- +-keep public class com.alibaba.android.arouter.routes.**{*;} +-keep public class com.alibaba.android.arouter.facade.**{*;} +-keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;} +# If you use the byType method to obtain Service, add the following rules to protect the interface: +-keep interface * implements com.alibaba.android.arouter.facade.template.IProvider +# If single-type injection is used, that is, no interface is defined to implement IProvider, the following rules need to be added to protect the implementation +# -keep class * implements com.alibaba.android.arouter.facade.template.IProvider + +#-----Glide----- +-keep public class * implements com.bumptech.glide.module.GlideModule +-keep public class * extends com.bumptech.glide.module.AppGlideModule { + (...); +} +-keep public enum com.bumptech.glide.load.ImageHeaderParser$** { + **[] $VALUES; + public *; +} +-keep class com.bumptech.glide.load.data.ParcelFileDescriptorRewinder$InternalRewinder { + *** rewind(); +} + +#如果你的 target API 低于 Android API 27,请添加: +-dontwarn com.bumptech.glide.load.resource.bitmap.VideoDecoder + +#-----Fresco----- +-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip +-keep,allowobfuscation @interface com.facebook.soloader.DoNotOptimize +-keep @com.facebook.common.internal.DoNotStrip class * +-keepclassmembers class * { + @com.facebook.common.internal.DoNotStrip *; +} +-keep @com.facebook.soloader.DoNotOptimize class * +-keepclassmembers class * { + @com.facebook.soloader.DoNotOptimize *; +} +-keepclassmembers class * { + native ; +} + +-keep public class com.facebook.soloader.SoLoader { + public static void init(android.content.Context, int); +} + +-dontwarn okio.** +-dontwarn com.squareup.okhttp.** +-dontwarn okhttp3.** +-dontwarn javax.annotation.** +-dontwarn com.android.volley.toolbox.** +-dontwarn com.facebook.infer.** + +#-----Okio----- +# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. +-dontwarn org.codehaus.mojo.animal_sniffer.* +-dontwarn com.squareup.** +-dontwarn okio.** + +#-----OkHttp----- +# JSR 305 annotations are for embedding nullability information. +-dontwarn javax.annotation.** +# A resource is loaded with a relative path so the package of this class must be preserved. +-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase +# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. +-dontwarn org.codehaus.mojo.animal_sniffer.* +# OkHttp platform used only on JVM and when Conscrypt dependency is available. +-dontwarn okhttp3.internal.platform.ConscryptPlatform + +#-----Retrofit----- +# Retrofit does reflection on method and parameter annotations. +-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations +# Retain service method parameters when optimizing. +-keepclassmembers,allowshrinking,allowobfuscation interface * { + @retrofit2.http.* ; +} +# Ignore annotation used for build tooling. +-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement +# Ignore JSR 305 annotations for embedding nullability information. +-dontwarn javax.annotation.** +# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath. +-dontwarn kotlin.Unit +# Top-level functions that can only be used by Kotlin. +-dontwarn retrofit2.KotlinExtensions +-dontwarn retrofit2.KotlinExtensions$* +# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy +# and replaces all potential values with null. Explicitly keeping the interfaces prevents this. +-if interface * { @retrofit2.http.* ; } +-keep,allowobfuscation interface <1> + +#-----ProtoBuf----- +-keep class com.google.protobuf.** {*;} + +#-----GSYVideoPlayer----- +-keep class com.shuyu.gsyvideoplayer.video.** { *; } +-dontwarn com.shuyu.gsyvideoplayer.video.** +-keep class com.shuyu.gsyvideoplayer.video.base.** { *; } +-dontwarn com.shuyu.gsyvideoplayer.video.base.** +-keep class com.shuyu.gsyvideoplayer.utils.** { *; } +-dontwarn com.shuyu.gsyvideoplayer.utils.** +-keep class tv.danmaku.ijk.** { *; } +-dontwarn tv.danmaku.ijk.** + +#-----EventBus----- +-keepattributes *Annotation* +-keepclassmembers class * { + @org.greenrobot.eventbus.Subscribe ; +} +-keep enum org.greenrobot.eventbus.ThreadMode { *; } +# And if you use AsyncExecutor: +-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent { + (java.lang.Throwable); +} + +#-----Netty----- +-keepattributes Signature,InnerClasses +-keep class io.netty.** {*;} +-keep class org.apache.** {*;} +-keep class org.apache.logging.**{*;} +-keepclasseswithmembers class io.netty.** {*;} +-keepclasseswithmembers class org.apache.logging.**{*;} +-keep class org.apache.http.**{*;} +-dontwarn io.netty.** +-dontwarn sun.** + +#-----ZhiDaoService----- +-keep class com.zhidao.auto.platform.**{*;} +-keep class com.zhidao.auto.carcorder.**{*;} +-keep class com.zhidaohulian.**{*;} +-keep class com.zhidao.boot.**{*;} +-keep class com.elegant.**{*;} +-keep class com.zhidao.socketsdk.**{*;} +-keep class com.zhidao.socket.**{*;} +-keep class com.zhidao.ptech.**{*;} +-keep class com.zhidao.autopilotcore.**{*;} +-keep class com.zhidao.autopilot.support.**{*;} +-keep class com.zhidao.voice.library.**{*;} +-keep class com.zhidao.voicesdk.**{*;} +-keep class com.zhidao.smartv2x.**{*;} +-keep class com.zhidao.accountsdk.**{*;} +-keep class com.zhidao.account.**{*;} +-keep class com.zhidao.locupload.**{*;} +-keep class com.zhidao.tcloginsdk.**{*;} +-keep class com.zhidao.utils.**{*;} +-keep class com.hw.videoprocessor.**{*;} +-dontwarn com.elegant.network.** + +-keep class com.bytedance.boost_multidex.**{*;} + + + + diff --git a/app/src/e8xx/AndroidManifest.xml b/app/src/e8xx/AndroidManifest.xml new file mode 100644 index 0000000000..d755054676 --- /dev/null +++ b/app/src/e8xx/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/app/src/em4/AndroidManifest.xml b/app/src/em4/AndroidManifest.xml new file mode 100644 index 0000000000..d755054676 --- /dev/null +++ b/app/src/em4/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/app/src/independent/AndroidManifest.xml b/app/src/independent/AndroidManifest.xml new file mode 100644 index 0000000000..57d7908a59 --- /dev/null +++ b/app/src/independent/AndroidManifest.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/launcher/AndroidManifest.xml b/app/src/launcher/AndroidManifest.xml new file mode 100644 index 0000000000..fa7c043148 --- /dev/null +++ b/app/src/launcher/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a1d4aa5c1c..ccf3dd8248 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,16 +1,31 @@ + + + android:theme="@style/AppTheme.App" + tools:replace="android:label"> + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/mogo/launcher/MogoApplication.java b/app/src/main/java/com/mogo/launcher/MogoApplication.java index 7a7ac48037..449ebf20d4 100644 --- a/app/src/main/java/com/mogo/launcher/MogoApplication.java +++ b/app/src/main/java/com/mogo/launcher/MogoApplication.java @@ -1,6 +1,36 @@ package com.mogo.launcher; -import android.app.Application; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; + +import com.alibaba.android.arouter.launcher.ARouter; +import com.auto.zhidao.logsdk.CrashSystem; +import com.bytedance.boost_multidex.BoostMultiDex; +import com.mogo.commons.AbsMogoApplication; +import com.mogo.commons.debug.DebugConfig; +import com.mogo.commons.network.Utils; +import com.mogo.commons.storage.SpStorage; +import com.mogo.module.authorize.authprovider.invoke.AuthorizeConstant; +import com.mogo.module.carchatting.card.CallChatConstant; +import com.mogo.module.common.MogoModule; +import com.mogo.module.common.MogoModulePaths; +import com.mogo.module.main.service.MogoMainService; +import com.mogo.module.media.MediaConstants; +import com.mogo.module.push.base.PushUIConstants; +import com.mogo.module.service.ServiceConst; +import com.mogo.module.tanlu.constant.TanluConstants; +import com.mogo.module.v2x.V2XConst; +import com.mogo.service.IMogoServiceApis; +import com.mogo.service.MogoServicePaths; +import com.mogo.service.passport.IMogoTicketCallback; +import com.mogo.utils.UiThreadHandler; +import com.mogo.utils.logger.LogLevel; +import com.mogo.utils.logger.Logger; +import com.zhidao.boot.persistent.lib.PersistentManager; +import com.zhidao.mogo.module.event.panel.EventPanelConstants; +import com.zhidao.mogo.module.left.panel.LeftPanelConst; /** * @author congtaowang @@ -8,10 +38,121 @@ import android.app.Application; *

* Launcher application */ -public class MogoApplication extends Application { +public class MogoApplication extends AbsMogoApplication { + + private static final String TAG = "MogoApplication"; @Override public void onCreate() { + initDebugConfig(); super.onCreate(); + // Crash 日志收集 + final long start = System.currentTimeMillis(); + CrashSystem crashSystem = CrashSystem.getInstance( this ); + crashSystem.init(); + //设置debug模式,日志不上传 + crashSystem.setDebug( BuildConfig.DEBUG ); + Logger.init( BuildConfig.DEBUG ? LogLevel.DEBUG : LogLevel.OFF ); + +// MogoModulePaths.addModule(new MogoModule(PATH_GUIDE_FRAGMENT, PATH_GUIDE_MODULE_NAME)); + MogoModulePaths.addModule( new MogoModule( MogoServicePaths.PATH_AGREEMENT, AuthorizeConstant.PATH_AGREEMENT_MODULE_NAME ) ); + + //运营位卡片,需要默认显示,放在第一个加载 + if (DebugConfig.isLauncher() ) { + MogoModulePaths.addModule( new MogoModule( MediaConstants.TAG, MediaConstants.MODULE_TYPE ) ); + } + if(DebugConfig.getCarMachineType() != DebugConfig.CAR_MACHINE_TYPE_BYD){ + MogoModulePaths.addModule( new MogoModule( CallChatConstant.PROVIDER, CallChatConstant.MODULE_NAME ) ); + } + MogoModulePaths.addModule( new MogoModule( TanluConstants.TAG, TanluConstants.MODEL_NAME ) ); + MogoModulePaths.addModule( new MogoModule( MogoServicePaths.PATH_SHARE, "ShareControl" ) ); + + MogoModulePaths.addModule( new MogoModule( EventPanelConstants.PATH_NAME, + EventPanelConstants.MODULE_NAME ) ); + MogoModulePaths.addModule( new MogoModule( LeftPanelConst.PATH_NAME, + LeftPanelConst.MODULE_NAME ) ); + + MogoModulePaths.addBaseModule( new MogoModule( ServiceConst.PATH_REFRESH_STRATEGY, ServiceConst.PATH_REFRESH_STRATEGY ) ); + MogoModulePaths.addBaseModule( new MogoModule( V2XConst.PATH_V2X_UI, V2XConst.PATH_V2X_UI ) ); + MogoModulePaths.addModule( new MogoModule( PushUIConstants.PATH, PushUIConstants.NAME ) ); + + if ( !DebugConfig.isLauncher() ) { + PersistentManager.getInstance().initManager( this ); + Intent intent = new Intent( this, MogoMainService.class ); + startService( intent ); + } + Log.i( "timer", "cost " + ( System.currentTimeMillis() - start ) + "ms" ); + } + + private void initDebugConfig() { + DebugConfig.setNetMode( BuildConfig.NET_ENV ); + DebugConfig.setDebug( BuildConfig.DEBUG ); + DebugConfig.setAIType( BuildConfig.AIType ); + DebugConfig.setLaunchLocationService( BuildConfig.LAUNCH_LOCATION_SERVICE ); + DebugConfig.setUseCustomNavi( BuildConfig.USE_CUSTOM_NAVI ); + DebugConfig.setLauncher( BuildConfig.IS_LAUNCHER ); + DebugConfig.setActiveAIAssistFlag( BuildConfig.AI_ASSIST_ACTIVE_STAUTS ); + DebugConfig.setCarMachineType( BuildConfig.CAR_MACHINE_TYPE ); + DebugConfig.setProductFlavor( BuildConfig.FLAVOR_product ); + DebugConfig.setSocketAppId( BuildConfig.SOCKET_APP_ID ); + } + + @Override + protected void init() { + super.init(); + prepareBaseService(2_000L); + } + + /** + * 基础服务:passport、location、socket + */ + private void prepareBaseService(long delay) { + UiThreadHandler.postDelayed( () -> { + final IMogoServiceApis apis = ARouter.getInstance().navigation( IMogoServiceApis.class ); + // 第三方平台的sn是服务端生成的,所以必须在返回后才能开启 + if ( TextUtils.isEmpty( Utils.getSn() ) ) { + preparePassportEnvironment( apis, () -> { + prepareSocketAndLocationServices( apis ); + } ); + } else { + preparePassportEnvironment( apis, null ); + prepareSocketAndLocationServices( apis ); + } + }, delay ); + } + + private void preparePassportEnvironment( IMogoServiceApis apis, Runnable after ) { + apis.getPassportManagerApi().requestTicket( new IMogoTicketCallback() { + @Override + public void onTicketGot( String ticket ) { + Logger.d( TAG, "ticket = %s", ticket ); + } + + @Override + public void onError( int code, String msg ) { + Logger.w( TAG, "code = %s, msg = %s", code, msg ); + } + + @Override + public void onLoginSuccess( String token, String sn ) { + if ( after != null ) { + after.run(); + } + } + } ); + } + + private void prepareSocketAndLocationServices( IMogoServiceApis apis ) { + apis.getSocketManagerApi( getApplicationContext() ).init( getApplicationContext(), DebugConfig.getSocketAppId() ); + apis.getLocationInfoApi().start(); + apis.getMapServiceApi().getSingletonLocationClient( getApplicationContext() ).addLocationListener( location -> { + apis.getLocationInfoApi().provideLocation( location ); + } ); + } + + @Override + protected void attachBaseContext( Context base ) { + super.attachBaseContext( base ); + BoostMultiDex.install( base ); } } diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 1f6bb29060..0000000000 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/app/src/main/res/drawable-xhdpi/ic_launcher.png b/app/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100755 index 0000000000..56c238207f Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/drawable/ic_launcher.png b/app/src/main/res/drawable/ic_launcher.png new file mode 100755 index 0000000000..9c5190b88a Binary files /dev/null and b/app/src/main/res/drawable/ic_launcher.png differ diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 0d025f9bf6..0000000000 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index eca70cfe52..0000000000 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index eca70cfe52..0000000000 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index dffca3601e..0000000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 64ba76f75e..0000000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index dae5e08234..0000000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 14ed0af350..0000000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index b0907cac3b..0000000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index d8ae031549..0000000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 2c18de9e66..0000000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index beed3cdd2c..0000000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/values-xhdpi-1920x1000/strings.xml b/app/src/main/res/values-xhdpi-1920x1000/strings.xml new file mode 100644 index 0000000000..4b537bbf4c --- /dev/null +++ b/app/src/main/res/values-xhdpi-1920x1000/strings.xml @@ -0,0 +1,3 @@ + + 蘑菇知途 + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 69b22338c6..bd09796588 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,4 +3,7 @@ #008577 #00574B #D81B60 + + + #1C1C1C diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 146d275293..8c30469045 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ - MogoLauncher + 蘑菇出行 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index e6b4523fd9..0973015c8f 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -9,13 +9,14 @@ diff --git a/build.gradle b/build.gradle index 53d9475dce..32a0f5815c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,9 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. apply from: "config.gradle" +apply from: "javadoc.gradle" + buildscript { - ext.kotlin_version = '1.3.61+' + ext.kotlin_version = '1.3.61' repositories { maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' @@ -18,7 +20,8 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.5.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - + classpath "com.alibaba:arouter-register:1.0.2" + classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -37,9 +40,60 @@ allprojects { } google() jcenter() +// flatDir { + // 由于Library module中引用了 youkuplayer 库的 aar,在多 module 的情况下, + // 其他的module编译会报错,所以需要在所有工程的repositories + // 下把Library module中的libs目录添加到依赖关系中 +// dirs project(':libraries:map-baidu').file('libs') +// } } + } task clean(type: Delete) { delete rootProject.buildDir } + +task cleanAll(type: Delete){ + group = "custom" + rootProject.allprojects { + println "delete ${it.buildDir}" + delete it.buildDir + } +} + +def getValueFromRootProperties(String key) { + File file = rootProject.file('gradle.properties') + String value = ""; + if (file.exists()) { + //加载资源 + InputStream inputStream = file.newDataInputStream(); + Properties properties = new Properties() + properties.load(inputStream) + + if (properties.containsKey(key)) { + value = properties.getProperty(key) + } + } + return value +} + +afterEvaluate { + rootProject.subprojects { project -> + project.afterEvaluate { + dependencies { + components { + all { ComponentMetadataDetails details -> + if (details.toString().endsWith("-SNAPSHOT")) { + details.changing = true + } + } + } + } + it.configurations.all { + resolutionStrategy.cacheChangingModulesFor 0, 'seconds' + } + + } + } +} diff --git a/config.gradle b/config.gradle index 5d361f9b3d..f0a58756c4 100644 --- a/config.gradle +++ b/config.gradle @@ -1,53 +1,176 @@ ext { + time = "" + android = [ - applicationId : "com.mogo.launcher", - compileSdkVersion: 29, - buildToolsVersion: "29.0.2", - minSdkVersion : 19, - targetSdkVersion : 22, - versionCode : 1, - versionName : "1.0.0", +// applicationId : "com.mogo.launcher", +// zhidadoApplicationId: "com.zhidao.launcher", +launcherApplicationId : "com.mogo.launcher", +independentApplicationId: "com.mogo.launcher.app", +compileSdkVersion : 28, +buildToolsVersion : "29.0.2", +minSdkVersion : 19, +targetSdkVersion : 22, ] dependencies = [ // androidx - androidxappcompat : "androidx.appcompat:appcompat:1.0.2", - androidxconstraintlayout: "androidx.constraintlayout:constraintlayout:1.1.3", + androidxappcompat : "androidx.appcompat:appcompat:1.0.2", + androidxccorektx : "androidx.core:core-ktx:1.2.0", + androidxconstraintlayout : "androidx.constraintlayout:constraintlayout:1.1.3", + boostmultidex : "com.bytedance.boost_multidex:boost_multidex:1.0.1", + androidxviewpager2 : "androidx.viewpager2:viewpager2:1.0.0", + androidxrecyclerview : "androidx.recyclerview:recyclerview:1.1.0", + androidxcardview : "androidx.cardview:cardview:1.0.0", + // flexbox + flexbox : 'com.google.android:flexbox:2.0.1', // 测试 - junit : "junit:junit:4.12", - androidxjunit : "androidx.test.ext:junit:1.1.0", - androidxespressocore : "androidx.test.espresso:espresso-core:3.1.1", + junit : "junit:junit:4.12", + androidxjunit : "androidx.test.ext:junit:1.1.0", + androidxespressocore : "androidx.test.espresso:espresso-core:3.1.1", // 地图 - amapnavi3dmap : "com.amap.api:navi-3dmap:latest.integration", - amapsearch : "com.amap.api:search:latest.integration", - amaplocation : "com.amap.api:location:latest.integration", + amapnavi3dmap : "com.amap.api:navi-3dmap:7.2.0_3dmap7.2.0", + amapsearch : "com.amap.api:search:7.1.0", + amaplocation : "com.amap.api:location:4.9.0", // json 转换 - gson : "com.google.code.gson:gson:2.8.4", + gson : "com.google.code.gson:gson:2.8.4", // 内存泄漏检测 - debugleakcanary : "com.squareup.leakcanary:leakcanary-android:1.6.1", - releaseleakcanary : "com.squareup.leakcanary:leakcanary-android-no-op:1.6.1", - testleakcanary : "com.squareup.leakcanary:leakcanary-android-no-op:1.6.1", + debugleakcanary : "com.squareup.leakcanary:leakcanary-android:1.6.1", + releaseleakcanary : "com.squareup.leakcanary:leakcanary-android-no-op:1.6.1", + testleakcanary : "com.squareup.leakcanary:leakcanary-android-no-op:1.6.1", //rxJava - rxjava : "io.reactivex.rxjava2:rxjava:2.2.2", - rxandroid : "io.reactivex.rxjava2:rxandroid:2.1.0", + rxjava : "io.reactivex.rxjava2:rxjava:2.2.2", + rxandroid : "io.reactivex.rxjava2:rxandroid:2.1.0", // arouter - arouter : "com.alibaba:arouter-api:1.5.0", - aroutercompiler : "com.alibaba:arouter-compiler:1.2.2", + arouter : "com.alibaba:arouter-api:1.5.0", + aroutercompiler : "com.alibaba:arouter-compiler:1.2.2", // glide - glide : 'com.github.bumptech.glide:glide:4.8.0', - glideokhttp3 : 'com.github.bumptech.glide:okhttp3-integration:4.8.0', - glideanno : 'com.github.bumptech.glide:annotations:4.8.0', - glidecompiler : 'com.github.bumptech.glide:compiler:4.8.0', - supportannos : "com.android.support:support-annotations:28.0.0", + glide : 'com.github.bumptech.glide:glide:4.8.0', + glideokhttp3 : 'com.github.bumptech.glide:okhttp3-integration:4.8.0', + glideanno : 'com.github.bumptech.glide:annotations:4.8.0', + glidecompiler : 'com.github.bumptech.glide:compiler:4.8.0', + supportannos : "com.android.support:support-annotations:28.0.0", // fresco - fresco : 'com.facebook.fresco:fresco:1.1.0', + fresco : 'com.facebook.fresco:fresco:1.1.0', // 公司服务 - 语音 - aiassist : "com.zhidaoauto.common:service:1.0.4", + aiassist : "com.zhidaoauto.common:service:1.0.4.10", + // 语音替换方案 暂时只用TTS 解决焦点问题 + aiassistReplace : "com.zhidao.mogoVoicesdk:voice:1.0.5", + // 公司服务 - 埋点 + analytics : "com.elegant.analytics:analytics:1.1.19", - // retrofit - retrofit : "com.squareup.retrofit2:retrofit:2.3.0", - retrofitadapter : "com.squareup.retrofit2:adapter-rxjava:2.1.0", - retrofitconvertergson : "com.squareup.retrofit2:converter-gson:2.3.0", - retrofitconverterscalars: "com.squareup.retrofit2:converter-scalars:2.1.0", + retrofit : "com.squareup.retrofit2:retrofit:2.6.0", + retrofitadapter : "com.squareup.retrofit2:adapter-rxjava2:2.6.0", + retrofitconvertergson : "com.squareup.retrofit2:converter-gson:2.6.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', + + // add for room + room : "android.arch.persistence.room:runtime:1.1.1", + roomAnnotationProcessor : 'android.arch.persistence.room:compiler:1.1.1', + + // rxjava2 with room + roomRxjava : "android.arch.persistence.room:rxjava2:1.1.1", + + // material + material : 'com.google.android.material:material:1.0.0', + + + // modules + moduletanlu : "com.mogo.module:module-tanlu:${MOGO_MODULE_TANLU_VERSION}", + moduleshare : "com.mogo.module:module-share:${MOGO_MODULE_SHARE_VERSION}", + mogocommons : "com.mogo.commons:mogo-commons:${MOGO_COMMONS_VERSION}", + mogoutils : "com.mogo.commons:mogo-utils:${MOGO_UTILS_VERSION}", + mapamap : "com.mogo.map:map-amap:${MAP_AMAP_VERSION}", + mapautomap : "com.mogo.map:map-autonavi:${MAP_AUTONAVI_VERSION}", + mogomap : "com.mogo.map:mogo-map:${MOGO_MAP_VERSION}", + mogomapapi : "com.mogo.map:mogo-map-api:${MOGO_MAP_API_VERSION}", + modulecommon : "com.mogo.module:module-common:${MOGO_MODULE_COMMON_VERSION}", + modulemain : "com.mogo.module:module-main:${MOGO_MODULE_MAIN_VERSION}", + modulemainlauncher : "com.mogo.module:module-main-launcher:${MOGO_MODULE_MAIN_LAUNCHER_VERSION}", + modulemainindependent : "com.mogo.module:module-main-independent:${MOGO_MODULE_MAIN_INDEPENDENT_VERSION}", + modulemap : "com.mogo.module:module-map:${MOGO_MODULE_MAP_VERSION}", + moduleservice : "com.mogo.module:module-service:${MOGO_MODULE_SERVICE_VERSION}", + mogoservice : "com.mogo.service:mogo-service:${MOGO_SERVICE_VERSION}", + 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.module:module-extensions:${MOGO_MODULE_EXTENSIONS_VERSION}", + carcall : "com.mogo.module.carchatting:module-carchatting:${CARCHATTING_VERSION}", + carcallprovider : "com.mogo.module.carchatting:module-carchatting-provider:${CARCHATTINGPROVIDER_VERSION}", +// guideshow : "com.mogo.module.guideshow:module-guideshow:${MOGO_MODULE_GUIDESHOW_VERSION}", +// guideshowprovider : "com.mogo.module.guideshow:module-guideshow-provider:${MOGO_MODULE_GUIDESHOW_PROVIDER_VERSION}", + // 在线车辆 + moduleonlinecar : "com.mogo.module:module-onlinecar:${MOGO_MODULE_ONLINECAR_VERSION}", + // V2X + moduleV2x : "com.mogo.module:module-v2x:${MOGO_MODULE_V2X_VERSION}", + modulemedia : "com.mogo.module:module-media:${MOGO_MODULE_MEDIA_VERSION}", + modulesearch : "com.mogo.module:module-search:${MOGO_MODULE_SEARCH_VERSION}", + // push + modulepush : "com.mogo.module:module-push:${MOGO_MODULE_PUSH_VERSION}", + modulepushbase : "com.mogo.module:module-push-base:${MOGO_MODULE_PUSH_BASE_VERSION}", + modulepushnoop : "com.mogo.module:module-push-noop:${MOGO_MODULE_PUSH_NOOP_VERSION}", + //运营位卡片 + moduleadcard : "com.mogo.module:module-adcard:${MOGO_MODULE_AD_CARD_VERSION}", + //统一返回键 + mogomoduleback : "com.mogo.module:module-back:${MOGO_MODULE_BACK_VERSION}", + mogomoduleauth : "com.mogo.module:module-authorize:${MOGO_MODULE_AUTHORIZE_VERSION}", + mogomoduleguide : "com.mogo.module:module-guide:${MOGO_MODULE_GUIDE_VERSION}", + // 长链 + socketsdk : 'com.zhidao.socketsdk:socketsdk:2.1.4', + socketsdkconnsvrprotoco : 'com.zhidao.ptech:connsvr-protoco:0.1.23', + socketsdkprotobufjava : 'com.google.protobuf:protobuf-java:3.5.1', + // OBU + moduleobu : "com.mogo.module:module-obu:${MOGO_MODULE_OBU_VERSION}", + + // + jetbrainsannotationsjava5: "org.jetbrains:annotations-java5:15.0", + + // 统一登录 + accountsdk : "com.zhidao.accountservice:account-sdk:1.0.8", + // crash + crashSdk : "com.zhidaoauto.crash.log:library:1.0.5", + kotlinstdlibjdk7 : "org.jetbrains.kotlin:kotlin-stdlib-jdk7", + + //探路 + videoarmv7 : "com.shuyu:gsyVideoPlayer-armv7a:7.1.2", + videoarm64 : "com.shuyu:gsyVideoPlayer-arm64:7.1.2", + videojava : "com.shuyu:gsyVideoPlayer-java:7.1.2", + eventbus : "org.greenrobot:eventbus:3.1.1", + + coroutinescore : "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1", + coroutinesandroid : "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1", + + aspectj : "org.aspectj:aspectjrt:1.8.9", + + // gps 模拟 + gpssimulator : "com.mogo.module:module-gps-simulator:${MOGO_MODULE_GPS_SIMULATOR_VERSION}", + gpssimulatordebug : "com.mogo.module:module-gps-simulator-debug:${MOGO_MODULE_GPS_SIMULATOR_DEBUG_VERSION}", + gpssimulatornoop : "com.mogo.module:module-gps-simulator-noop:${MOGO_MODULE_GPS_SIMULATOR_NOOP_VERSION}", + + adasapi : "com.zhidao.autopilot.support:adas:1.0.1", + + // 个人中心的SDK + personalsdk : "com.zhidaoauto.person.info:data:1.0.1", + tanluupload : "com.mogo.module:module-tanlu-upload:${TANLULIB_VERSION}", + + // obu sdk + obusdk : "com.zhidao.enterprise.smartv2x:smartv2x:1.0.0.1", + //事件面板 + moduleventpanel : "com.mogo.module:module-event-panel:${MOGO_MODULE_EVENT_PANEL_VERSION}", + // 事件面板空实现 + moduleventpanelnoop : "com.mogo.module:module-event-panel-noop:${MOGO_MODULE_EVENT_PANEL_VERSION}", + // 左侧面板 + moduleleftpanel : "com.mogo.module:module-left-panel:${MOGO_MODULE_LEFT_PANEL_VERSION}", + // 左侧面板空实现 + moduleleftpanelnoop : "com.mogo.module:module-left-panel-noop:${MOGO_MODULE_LEFT_PANEL_VERSION}", + // 闪屏页 + modulesplash : "com.mogo.module:module-splash:${MOGO_MODULE_SPLASH_VERSION}", + // 基础服务实现 + mogobaseservicesdk : "com.mogo.base:services-sdk:${MOGO_BASE_SERVICES_SDK_VERSION}", + mogobaseserviceapk : "com.mogo.base:services-apk:${MOGO_BASE_SERVICES_APK_VERSION}", ] } \ No newline at end of file diff --git a/foudations/mogo-base-services-apk/.gitignore b/foudations/mogo-base-services-apk/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/foudations/mogo-base-services-apk/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/foudations/mogo-base-services-apk/README.md b/foudations/mogo-base-services-apk/README.md new file mode 100644 index 0000000000..b6ee9eafae --- /dev/null +++ b/foudations/mogo-base-services-apk/README.md @@ -0,0 +1,7 @@ +## 基实现功能 + +基础服务apk实现对应功能:位置上报、长连接、passport + +位置上报:com.zhidao.locationinfo +长链:com.zhidao.socketservice +passport: \ No newline at end of file diff --git a/foudations/mogo-base-services-apk/build.gradle b/foudations/mogo-base-services-apk/build.gradle new file mode 100644 index 0000000000..943521aac6 --- /dev/null +++ b/foudations/mogo-base-services-apk/build.gradle @@ -0,0 +1,51 @@ +apply plugin: 'com.android.library' + +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") + + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: "libs", include: ["*.jar"]) + implementation rootProject.ext.dependencies.arouter + + api rootProject.ext.dependencies.socketsdk + api rootProject.ext.dependencies.socketsdkconnsvrprotoco + api rootProject.ext.dependencies.socketsdkprotobufjava + implementation rootProject.ext.dependencies.accountsdk + + if (Boolean.valueOf(RELEASE)) { + implementation rootProject.ext.dependencies.mogoutils + implementation rootProject.ext.dependencies.mogocommons + implementation rootProject.ext.dependencies.mogoserviceapi + } else { + implementation project(":foudations:mogo-utils") + implementation project(":foudations:mogo-commons") + implementation project(":services:mogo-service-api") + } + +} + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() \ No newline at end of file diff --git a/foudations/mogo-base-services-apk/consumer-rules.pro b/foudations/mogo-base-services-apk/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/foudations/mogo-base-services-apk/gradle.properties b/foudations/mogo-base-services-apk/gradle.properties new file mode 100644 index 0000000000..aae1d6638c --- /dev/null +++ b/foudations/mogo-base-services-apk/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.base +POM_ARTIFACT_ID=services-apk +VERSION_CODE=1 diff --git a/foudations/mogo-base-services-apk/proguard-rules.pro b/foudations/mogo-base-services-apk/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/foudations/mogo-base-services-apk/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/foudations/mogo-utils/src/androidTest/java/com/mogo/utils/ExampleInstrumentedTest.java b/foudations/mogo-base-services-apk/src/androidTest/java/com/mogo/base/services/apk/ExampleInstrumentedTest.java similarity index 83% rename from foudations/mogo-utils/src/androidTest/java/com/mogo/utils/ExampleInstrumentedTest.java rename to foudations/mogo-base-services-apk/src/androidTest/java/com/mogo/base/services/apk/ExampleInstrumentedTest.java index dca1040e3f..3588462fba 100644 --- a/foudations/mogo-utils/src/androidTest/java/com/mogo/utils/ExampleInstrumentedTest.java +++ b/foudations/mogo-base-services-apk/src/androidTest/java/com/mogo/base/services/apk/ExampleInstrumentedTest.java @@ -1,4 +1,4 @@ -package com.mogo.utils; +package com.mogo.base.services.apk; import android.content.Context; @@ -21,7 +21,6 @@ public class ExampleInstrumentedTest { public void useAppContext() { // Context of the app under test. Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - - assertEquals( "com.mogo.utils.test", appContext.getPackageName() ); + assertEquals( "com.mogo.base.services.apk.test", appContext.getPackageName() ); } -} +} \ No newline at end of file diff --git a/foudations/mogo-base-services-apk/src/main/AndroidManifest.xml b/foudations/mogo-base-services-apk/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..a82c409551 --- /dev/null +++ b/foudations/mogo-base-services-apk/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + / + \ No newline at end of file diff --git a/foudations/mogo-base-services-apk/src/main/java/com/mogo/base/services/locationinfo/MogoLocationInfoServices.java b/foudations/mogo-base-services-apk/src/main/java/com/mogo/base/services/locationinfo/MogoLocationInfoServices.java new file mode 100644 index 0000000000..5a6c31d624 --- /dev/null +++ b/foudations/mogo-base-services-apk/src/main/java/com/mogo/base/services/locationinfo/MogoLocationInfoServices.java @@ -0,0 +1,63 @@ +package com.mogo.base.services.locationinfo; + +import android.content.Context; + +import androidx.annotation.Keep; + +import com.mogo.map.location.MogoLocation; +import com.mogo.service.locationinfo.IMogoLocationInfoService; +import com.mogo.utils.logger.Logger; + +public +/** + * @author congtaowang + * @since 2020/7/16 + * + * 位置服务 + */ +@Keep +class MogoLocationInfoServices implements IMogoLocationInfoService { + + private static final String TAG = "MogoLocationInfoServices-apk"; + + private static volatile MogoLocationInfoServices sInstance; + + private MogoLocationInfoServices() { + } + + @Keep + public static MogoLocationInfoServices getInstance() { + if ( sInstance == null ) { + synchronized ( MogoLocationInfoServices.class ) { + if ( sInstance == null ) { + sInstance = new MogoLocationInfoServices(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + @Override + public void provideLocation( MogoLocation location ) { + Logger.d( TAG, "apk - provideLocation" ); + } + + @Override + public void start() { + Logger.d( TAG, "apk - start" ); + } + + @Override + public void stop() { + Logger.d( TAG, "apk - stop" ); + } + + @Override + public void init( Context context ) { + Logger.d( TAG, "apk - init" ); + } +} diff --git a/foudations/mogo-base-services-apk/src/main/java/com/mogo/base/services/passport/PassportManager.java b/foudations/mogo-base-services-apk/src/main/java/com/mogo/base/services/passport/PassportManager.java new file mode 100644 index 0000000000..2a23051695 --- /dev/null +++ b/foudations/mogo-base-services-apk/src/main/java/com/mogo/base/services/passport/PassportManager.java @@ -0,0 +1,87 @@ +package com.mogo.base.services.passport; + +import android.content.Context; + +import androidx.annotation.Keep; + +import com.mogo.commons.debug.DebugConfig; +import com.mogo.commons.storage.SpStorage; +import com.mogo.service.passport.IMogoPassportManager; +import com.mogo.service.passport.IMogoTicketCallback; +import com.mogo.utils.logger.Logger; +import com.zhidao.account.sdk.AccountClientManager; +import com.zhidao.account.sdk.callback.TicketInfoCallback; +import com.zhidao.account.sdk.network.NetEnvironManager; + +public +/** + * @author congtaowang + * @since 2020/7/16 + * + * 描述 + */ +@Keep +class PassportManager implements IMogoPassportManager { + + private static final String TAG = "PassportManager-apk"; + + private static volatile PassportManager sInstance; + + private PassportManager(){} + + @Keep + public static PassportManager getInstance(){ + if( sInstance == null ){ + synchronized( PassportManager.class ) { + if( sInstance == null ){ + sInstance = new PassportManager(); + } + } + } + return sInstance; + } + + public synchronized void release(){ + sInstance = null; + } + + @Override + public void requestTicket( final IMogoTicketCallback callback ) { + getTicket( new TicketInfoCallback() { + @Override + public void onSuccess( String ticket ) { + Logger.d( TAG, "success" ); + SpStorage.setTicket( ticket ); + if ( callback != null ) { + callback.onTicketGot( ticket ); + } + } + + @Override + public void onFailure( int code, String msg ) { + Logger.d( TAG, "fail" ); + if ( callback != null ) { + callback.onError( code, msg ); + } + } + } ); + } + + private static void getTicket( TicketInfoCallback callback ) { + if ( DebugConfig.isLauncher() ) { + AccountClientManager.getTicket( callback ); + } else { + AccountClientManager.getAppTicket( callback ); + } + } + + @Override + public void init( Context context ) { + int mode = DebugConfig.getNetMode(); + if ( mode == DebugConfig.NET_MODE_DEMO ) { + // 演示环境用 qa 的 + mode = DebugConfig.NET_MODE_QA; + } + AccountClientManager.init( context.getApplicationContext(), mode, NetEnvironManager.OS_2C, "os2.0-launcher" ); + } +} diff --git a/foudations/mogo-base-services-apk/src/main/java/com/mogo/base/services/socket/SocketManager.java b/foudations/mogo-base-services-apk/src/main/java/com/mogo/base/services/socket/SocketManager.java new file mode 100644 index 0000000000..22e6fb427c --- /dev/null +++ b/foudations/mogo-base-services-apk/src/main/java/com/mogo/base/services/socket/SocketManager.java @@ -0,0 +1,228 @@ +package com.mogo.base.services.socket; + +import android.content.Context; + +import androidx.annotation.Keep; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mogo.service.connection.IMogoMsgAckListener; +import com.mogo.service.connection.IMogoOnMessageListener; +import com.mogo.service.connection.IMogoSocketManager; +import com.mogo.service.connection.MsgBody; +import com.mogo.utils.logger.Logger; +import com.mogo.utils.network.utils.GsonUtil; +import com.zhidao.ptech.connsvr.commom.protocol.MogoCommon; +import com.zhidao.ptech.connsvr.protocol.MogoConnsvr; +import com.zhidao.socketsdk.manager.OnSocketAckCallback; +import com.zhidao.socketsdk.manager.OnSocketReceiveCallback; +import com.zhidao.socketsdk.manager.SocketConnManager; +import com.zhidao.socketsdk.manager.SocketConnManagerImpl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author congtaowang + * @since 2019-12-31 + *

+ * 长链实现:基于 netty + */ +@Keep +public class SocketManager implements IMogoSocketManager, OnSocketReceiveCallback, OnSocketAckCallback { + + private static final String TAG = "SocketManager-apk"; + + public static final int MSG_PRODUCT_LINE = MogoCommon.Product.mogoBussiness_VALUE; + private static final int MSG_HEADER_TYPE = MogoConnsvr.MsgType.mogoMsgTypeDispatchSvrNoRspReq_VALUE; + + private static volatile SocketManager sInstance; + + private SocketManager( Context context ) { + mSocketConnManager = SocketConnManagerImpl.getInstance( context ); + mSocketConnManager.addSocketMessageCallback( this ); + mSocketConnManager.addSocketAckCallback( this ); + } + + @Keep + public static SocketManager getInstance( Context context ) { + if ( sInstance == null ) { + synchronized ( SocketManager.class ) { + if ( sInstance == null ) { + sInstance = new SocketManager( context ); + } + } + } + return sInstance; + } + + /** + * 管理消息分发 + *

+ * key - msgType + */ + private Map< Integer, List< IMogoOnMessageListener > > mListeners = new ConcurrentHashMap<>(); + + /** + * 管理消息回执 + *

+ * key - msgId + */ + private Map< Long, IMogoMsgAckListener > mAckListeners = new ConcurrentHashMap<>(); + + + private SocketConnManager mSocketConnManager; + public static final int MAX_CAP = 64; //保证充足的容量应对非常延时的推送 + private ArrayList< Long > mReceivedMsgId = new ArrayList<>( MAX_CAP ); + private int mCurrentIndex = 0; + + @Override + public void init( Context context, String appId ) { + if ( mSocketConnManager != null ) { + mSocketConnManager.init( appId ); + } + } + + @Override + public void onMessageReceived( byte[] content ) { + onMessageReceived( content, 0); + } + + public void onMessageReceived( byte[] content, long msgId ) { + try { + MogoConnsvr.Payload payload = MogoConnsvr.Payload.parseFrom( content ); + int msgType = payload.getMsgType(); + Logger.d( TAG, "received msg type = %d", msgType ); + List< IMogoOnMessageListener > listeners = mListeners.get( msgType ); + if ( listeners != null && !listeners.isEmpty() ) { + Iterator< IMogoOnMessageListener > iterator = listeners.iterator(); + if ( msgId != 0 ) { //兼容老版本 + if ( mReceivedMsgId.contains( msgId ) ) { // 避免消息重发 + return; + } + cacheLastReceivedMsgId( msgId ); + } + Object object = null; + while ( iterator.hasNext() ) { + IMogoOnMessageListener listener = iterator.next(); + if ( object == null ) { + object = GsonUtil.objectFromJson( payload.getPayload().toStringUtf8(), listener.target() ); + } + if ( listener != null ) { + Logger.d( TAG, "received msgId = %s, content = %s", msgId, payload.getPayload().toStringUtf8() ); + listener.onMsgReceived( object ); + } + } + } + } catch ( InvalidProtocolBufferException e ) { + Logger.e( TAG, e, "parse msg error." ); + } + } + + private void cacheLastReceivedMsgId( long msgId ) { + if ( msgId == 0 ) { + return; + } + synchronized ( this ){ + mReceivedMsgId.add( mCurrentIndex % MAX_CAP, msgId ); + mCurrentIndex++; + } + } + + @Override + public void onAck( byte[] headerBytes, byte[] payloadBytes ) { + try { + MogoConnsvr.Header header = MogoConnsvr.Header.parseFrom( headerBytes ); + int msgType = header.getMsgType(); + String appId = header.getAppId(); + int productLine = header.getProductLine(); + long msgId = header.getMsgId(); + IMogoMsgAckListener listener = mAckListeners.remove( msgId ); + if ( listener != null ) { + listener.onAck( msgId ); + } + Logger.d( TAG, "send message success: msgType = %d, appId = %s, productLine = %d", msgType, appId, productLine ); + } catch ( InvalidProtocolBufferException e ) { + e.printStackTrace(); + } + } + + @Override + public void registerOnMessageListener( int msgType, IMogoOnMessageListener listener ) { + if ( mListeners.containsKey( msgType ) ) { + Logger.w( TAG, "msgType %d is exist.", msgType ); + } + if ( !mListeners.containsKey( msgType ) ) { + mListeners.put( msgType, new ArrayList< IMogoOnMessageListener >() ); + } + mListeners.get( msgType ).add( listener ); + } + + @Override + public void unregisterOnMessageListener( int msgType ) { + mListeners.remove( msgType ); + } + + @Override + public void unregisterOnMessageListener( int msgType, IMogoOnMessageListener listener ) { + if ( listener == null ) { + return; + } + if ( !mListeners.containsKey( msgType ) ) { + return; + } + List< IMogoOnMessageListener > listeners = mListeners.get( msgType ); + if ( listeners != null && listeners.contains( listener ) ) { + listeners.remove( listener ); + } + } + + @Override + public void sendMsg( MsgBody body, IMogoMsgAckListener listener ) { + Logger.d( TAG, "sendMsg." ); + if ( mSocketConnManager != null ) { + if ( mSocketConnManager.isConnected() ) { + Logger.d( TAG, "isConnected." ); + final byte[] pb = convertToPBBytes( body.getMsgType(), objectToBytes( body.getContent() ) ); + mSocketConnManager.sendPayload( + MSG_PRODUCT_LINE, + pb, + MSG_HEADER_TYPE, + body.isAck(), + body.getMsgId() + ); + mAckListeners.put( body.getMsgId(), listener ); + } else { + Logger.e( TAG, "sendMsg error, connect is lost." ); + } + } else { + Logger.e( TAG, "sendMsg error, client is null." ); + } + } + + public byte[] objectToBytes( Object obj ) { + String jsonStr = GsonUtil.jsonFromObject( obj ); + return jsonStr.getBytes(); + } + + private byte[] convertToPBBytes( int msgType, byte[] payloadBytes ) { + MogoConnsvr.Payload payloadData = MogoConnsvr.Payload.newBuilder() + .setMsgType( msgType ) + .setPayload( ByteString.copyFrom( payloadBytes ) ).build(); + return payloadData.toByteArray(); + } + + public synchronized void release() { + mListeners.clear(); + mListeners = null; + sInstance = null; + } + + + @Override + public void init( Context context ) { + } +} diff --git a/app/src/test/java/com/mogo/launcher/ExampleUnitTest.java b/foudations/mogo-base-services-apk/src/test/java/com/mogo/base/services/apk/ExampleUnitTest.java similarity index 90% rename from app/src/test/java/com/mogo/launcher/ExampleUnitTest.java rename to foudations/mogo-base-services-apk/src/test/java/com/mogo/base/services/apk/ExampleUnitTest.java index cde4cc10d4..7b81601a73 100644 --- a/app/src/test/java/com/mogo/launcher/ExampleUnitTest.java +++ b/foudations/mogo-base-services-apk/src/test/java/com/mogo/base/services/apk/ExampleUnitTest.java @@ -1,4 +1,4 @@ -package com.mogo.launcher; +package com.mogo.base.services.apk; import org.junit.Test; diff --git a/foudations/mogo-base-services-sdk/.gitignore b/foudations/mogo-base-services-sdk/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/foudations/mogo-base-services-sdk/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/foudations/mogo-base-services-sdk/README.md b/foudations/mogo-base-services-sdk/README.md new file mode 100644 index 0000000000..d5fa09de5b --- /dev/null +++ b/foudations/mogo-base-services-sdk/README.md @@ -0,0 +1,3 @@ +## sdk实现功能 + +脱离基础服务apk实现对应功能:位置上报、长连接、passport \ No newline at end of file diff --git a/foudations/mogo-base-services-sdk/build.gradle b/foudations/mogo-base-services-sdk/build.gradle new file mode 100644 index 0000000000..7237542631 --- /dev/null +++ b/foudations/mogo-base-services-sdk/build.gradle @@ -0,0 +1,53 @@ +apply plugin: 'com.android.library' + +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") + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation fileTree(dir: "libs", include: ["*.jar"]) + implementation rootProject.ext.dependencies.arouter + // 上报位置 + implementation 'com.zhidao.locupload:loc-upload-sdk:1.1.3' + // 长链 + implementation 'com.zhidao.socket:built-in-socket:1.0.15' + // passport + implementation 'com.zhidao.tcloginsdk:tclogin:1.1.0' + + annotationProcessor 'com.elegant.spi:compiler:1.0.3' + + + if (Boolean.valueOf(RELEASE)) { + implementation rootProject.ext.dependencies.mogoutils + implementation rootProject.ext.dependencies.mogocommons + implementation rootProject.ext.dependencies.mogoserviceapi + } else { + implementation project(":foudations:mogo-utils") + implementation project(":foudations:mogo-commons") + implementation project(":services:mogo-service-api") + } +} + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() \ No newline at end of file diff --git a/foudations/mogo-base-services-sdk/consumer-rules.pro b/foudations/mogo-base-services-sdk/consumer-rules.pro new file mode 100644 index 0000000000..e4c27a022e --- /dev/null +++ b/foudations/mogo-base-services-sdk/consumer-rules.pro @@ -0,0 +1,2 @@ +#-----MogoBaseServiceSdk----- +-keep class com.mogo.base.services.locationinfo.MogoLocationSource.*{*;} \ No newline at end of file diff --git a/foudations/mogo-base-services-sdk/gradle.properties b/foudations/mogo-base-services-sdk/gradle.properties new file mode 100644 index 0000000000..ce31a0de78 --- /dev/null +++ b/foudations/mogo-base-services-sdk/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.base +POM_ARTIFACT_ID=services-sdk +VERSION_CODE=1 \ No newline at end of file diff --git a/foudations/mogo-base-services-sdk/proguard-rules.pro b/foudations/mogo-base-services-sdk/proguard-rules.pro new file mode 100644 index 0000000000..ba8f820823 --- /dev/null +++ b/foudations/mogo-base-services-sdk/proguard-rules.pro @@ -0,0 +1,24 @@ +# 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 + +#-----MogoBaseServiceSdk----- +-keep class com.mogo.base.services.locationinfo.MogoLocationSource.*{*;} \ No newline at end of file diff --git a/app/src/androidTest/java/com/mogo/launcher/ExampleInstrumentedTest.java b/foudations/mogo-base-services-sdk/src/androidTest/java/com/mogo/base/services/ExampleInstrumentedTest.java similarity index 84% rename from app/src/androidTest/java/com/mogo/launcher/ExampleInstrumentedTest.java rename to foudations/mogo-base-services-sdk/src/androidTest/java/com/mogo/base/services/ExampleInstrumentedTest.java index 2784cd1c3f..856a560f77 100644 --- a/app/src/androidTest/java/com/mogo/launcher/ExampleInstrumentedTest.java +++ b/foudations/mogo-base-services-sdk/src/androidTest/java/com/mogo/base/services/ExampleInstrumentedTest.java @@ -1,4 +1,4 @@ -package com.mogo.launcher; +package com.mogo.base.services; import android.content.Context; @@ -21,7 +21,6 @@ public class ExampleInstrumentedTest { public void useAppContext() { // Context of the app under test. Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - - assertEquals( "com.mogo.launcher", appContext.getPackageName() ); + assertEquals( "com.mogo.base.services.test", appContext.getPackageName() ); } -} +} \ No newline at end of file diff --git a/foudations/mogo-base-services-sdk/src/main/AndroidManifest.xml b/foudations/mogo-base-services-sdk/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..d7ee25b198 --- /dev/null +++ b/foudations/mogo-base-services-sdk/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + / + \ No newline at end of file diff --git a/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/BaseServicesConstants.java b/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/BaseServicesConstants.java new file mode 100644 index 0000000000..5d4c38a17a --- /dev/null +++ b/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/BaseServicesConstants.java @@ -0,0 +1,16 @@ +package com.mogo.base.services; + +public +/** + * @author congtaowang + * @since 2020/7/23 + * + * 描述 + */ +interface BaseServicesConstants { + + /** + * 建立长链的通道ID + */ + String SOCKET_CHANNEL_ID = "dataCrawler"; +} diff --git a/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/locationinfo/MogoLocationInfoServices.java b/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/locationinfo/MogoLocationInfoServices.java new file mode 100644 index 0000000000..8ecd0cb034 --- /dev/null +++ b/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/locationinfo/MogoLocationInfoServices.java @@ -0,0 +1,80 @@ +package com.mogo.base.services.locationinfo; + +import android.content.Context; + +import androidx.annotation.Keep; + +import com.mogo.commons.debug.DebugConfig; +import com.mogo.map.location.MogoLocation; +import com.mogo.service.locationinfo.IMogoLocationInfoService; +import com.mogo.utils.logger.Logger; +import com.zhidao.locupload.LocEnvironment; +import com.zhidao.locupload.LocUploadConfig; +import com.zhidao.locupload.LocUploadManager; + +public +/** + * @author congtaowang + * @since 2020/7/16 + * + * 位置服务 + */ +@Keep +class MogoLocationInfoServices implements IMogoLocationInfoService { + + private static final String TAG = "MogoLocationInfoServices-sdk"; + + private static volatile MogoLocationInfoServices sInstance; + private MogoLocation mLocation; + + private MogoLocationInfoServices() { + } + + @Keep + public static MogoLocationInfoServices getInstance() { + if ( sInstance == null ) { + synchronized ( MogoLocationInfoServices.class ) { + if ( sInstance == null ) { + sInstance = new MogoLocationInfoServices(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + @Override + public void provideLocation( MogoLocation location ) { + mLocation = location; + Logger.d( TAG, "sdk - provideLocation" ); + } + + public MogoLocation getLocation() { + return mLocation; + } + + @Override + public void start() { + LocUploadManager.getInstance().startUpload(); + Logger.d( TAG, "sdk - start" ); + } + + @Override + public void stop() { + LocUploadManager.getInstance().stopUpload(); + Logger.d( TAG, "sdk - stop" ); + } + + @Override + public void init( Context context ) { + LocUploadConfig.instance(). + setAppId( DebugConfig.getSocketAppId() ). + setContext( context.getApplicationContext() ). + setLoggable( DebugConfig.isDebug() ). + setLocInterval( 2000L ); + Logger.d( TAG, "sdk - init" ); + } +} diff --git a/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/locationinfo/MogoLocationSource.java b/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/locationinfo/MogoLocationSource.java new file mode 100644 index 0000000000..844abb4a98 --- /dev/null +++ b/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/locationinfo/MogoLocationSource.java @@ -0,0 +1,133 @@ +package com.mogo.base.services.locationinfo; + +import com.elegant.spi.annotations.Service; +import com.zhidao.locupload.location.LocationServiceProvider; + +public +/** + * @author congtaowang + * @since 2020/7/16 + * + * 描述 + */ +@Service( value = LocationServiceProvider.class ) +class MogoLocationSource extends LocationServiceProvider { + + @Override + public float getBearing() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getBearing(); + } + return 0; + } + + @Override + public float getAccuracy() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getAccuracy(); + } + return 0; + } + + @Override + public String getProvider() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getProvider(); + } + return null; + } + + @Override + public float getSpeed() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getSpeed(); + } + return 0; + } + + @Override + public double getAltitude() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getAltitude(); + } + return 0; + } + + @Override + public String getAdCode() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getAdCode(); + } + return null; + } + + @Override + public int getLocType() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getLocType(); + } + return 0; + } + + @Override + public double getLatitude() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getLatitude(); + } + return 0; + } + + @Override + public double getLongitude() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getLongitude(); + } + return 0; + } + + @Override + public long getTime() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getTime(); + } + return 0; + } + + @Override + public String getCityCode() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getCityCode(); + } + return null; + } + + @Override + public String getCityName() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getCityName(); + } + return null; + } + + @Override + public int getGpsAccuracyStatus() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getGpsAccuracyStatus(); + } + return 0; + } + + @Override + public int getSatellites() { + if ( MogoLocationInfoServices.getInstance().getLocation() != null ) { + return MogoLocationInfoServices.getInstance().getLocation().getSatellite(); + } + return 0; + } + + @Override + public int getCarStatus() { + // 常开状态 + return 1; + } +} diff --git a/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/passport/PassportManager.java b/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/passport/PassportManager.java new file mode 100644 index 0000000000..8f77ef1ecb --- /dev/null +++ b/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/passport/PassportManager.java @@ -0,0 +1,118 @@ +package com.mogo.base.services.passport; + +import android.content.Context; + +import androidx.annotation.Keep; + +import com.mogo.commons.debug.DebugConfig; +import com.mogo.commons.storage.SpStorage; +import com.mogo.service.passport.IMogoPassportManager; +import com.mogo.service.passport.IMogoTicketCallback; +import com.mogo.utils.logger.Logger; +import com.zhidao.accountsdk.manager.CarPadClientManagerImpl; +import com.zhidao.accountsdk.manager.TicketInfoCallback; +import com.zhidao.tcloginsdk.LoginManager; +import com.zhidao.tcloginsdk.model.TokenData; +import com.zhidao.tcloginsdk.network.LoginCallback; + +public +/** + * @author congtaowang + * @since 2020/7/16 + * + * 描述 + */ +@Keep +class PassportManager implements IMogoPassportManager { + + private static final String TAG = "PassportManager-sdk"; + private Context mContext; + + private static volatile PassportManager sInstance; + + private PassportManager() { + } + + @Keep + public static PassportManager getInstance() { + if ( sInstance == null ) { + synchronized ( PassportManager.class ) { + if ( sInstance == null ) { + sInstance = new PassportManager(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + @Override + public void requestTicket( final IMogoTicketCallback callback ) { + LoginManager.getInstance( mContext ).login( DebugConfig.getCarMachineType() != DebugConfig.CAR_MACHINE_TYPE_SELF_INNOVATE, DebugConfig.getProductFlavor(), new LoginCallback() { + @Override + public void onSuccess( TokenData.TokenResult result ) { + if ( callback != null ) { + callback.onLoginSuccess( result.token, result.sn ); + } + getTicket( new TicketInfoCallback() { + @Override + public void onSuccess( String ticket ) { + Logger.d( TAG, "success" ); + SpStorage.setTicket( ticket ); + if ( callback != null ) { + callback.onTicketGot( ticket ); + } + } + + @Override + public void onFailure( int code ) { + Logger.d( TAG, "fail" ); + if ( callback != null ) { + callback.onError( code, "getTicket error." ); + } + } + } ); + } + + @Override + public void onFailure( int code, String msg ) { + if ( callback != null ) { + callback.onError( code, "login: " + msg ); + } + } + } ); + + } + + private void getTicket( TicketInfoCallback callback ) { + CarPadClientManagerImpl.getInstance( mContext ).getTicket( "os2.0-launcher", new TicketInfoCallback() { + @Override + public void onSuccess( String ticket ) { + if ( callback != null ) { + callback.onSuccess( ticket ); + } + } + + @Override + public void onFailure( int code ) { + if ( callback != null ) { + callback.onFailure( code ); + } + } + } ); + } + + @Override + public void init( Context context ) { + mContext = context; + int mode = DebugConfig.getNetMode(); + if ( mode == DebugConfig.NET_MODE_DEMO ) { + // 演示环境用 qa 的 + mode = DebugConfig.NET_MODE_QA; + } + LoginManager.getInstance( context ).setNetEnviron( mode ); + } +} diff --git a/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/socket/SocketManager.java b/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/socket/SocketManager.java new file mode 100644 index 0000000000..f9520decf1 --- /dev/null +++ b/foudations/mogo-base-services-sdk/src/main/java/com/mogo/base/services/socket/SocketManager.java @@ -0,0 +1,231 @@ +package com.mogo.base.services.socket; + +import android.content.Context; + +import androidx.annotation.Keep; +import androidx.annotation.NonNull; + +import com.google.protobuf.ByteString; +import com.google.protobuf.InvalidProtocolBufferException; +import com.mogo.base.services.BaseServicesConstants; +import com.mogo.commons.debug.DebugConfig; +import com.mogo.commons.network.Utils; +import com.mogo.service.connection.IMogoMsgAckListener; +import com.mogo.service.connection.IMogoOnMessageListener; +import com.mogo.service.connection.IMogoSocketManager; +import com.mogo.service.connection.MsgBody; +import com.mogo.utils.logger.Logger; +import com.mogo.utils.network.utils.GsonUtil; +import com.zhidao.locupload.Platform; +import com.zhidao.ptech.connsvr.protocol.MogoConnsvr; +import com.zhidao.socket.Callback; +import com.zhidao.socket.CallbackManager; +import com.zhidao.socket.Environment; +import com.zhidao.socket.SocketConfig; +import com.zhidao.socket.SocketMessageDispatcher; +import com.zhidao.socket.utils.RequestUtil; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public +/** + * @author congtaowang + * @since 2020/7/16 + * + * 长链 + */ +@Keep +class SocketManager implements IMogoSocketManager, Callback { + + private static final String TAG = "SocketManager-sdk"; + + private static volatile SocketManager sInstance; + private String mAppId; + + public SocketManager( Context context ) { + CallbackManager.getInstance().register( this ); + } + + @Keep + public static SocketManager getInstance( Context context ) { + if ( sInstance == null ) { + synchronized ( SocketManager.class ) { + if ( sInstance == null ) { + sInstance = new SocketManager( context ); + } + } + } + return sInstance; + } + + /** + * 管理消息分发 + *

+ * key - msgType + */ + private Map< Integer, List< IMogoOnMessageListener > > mListeners = new ConcurrentHashMap<>(); + + /** + * 管理消息回执 + *

+ * key - msgId + */ + private Map< Long, IMogoMsgAckListener > mAckListeners = new ConcurrentHashMap<>(); + + + public static final int MAX_CAP = 64; //保证充足的容量应对非常延时的推送 + private ArrayList< Long > mReceivedMsgId = new ArrayList<>( MAX_CAP ); + private int mCurrentIndex = 0; + + @Override + public void init( Context context, String appId ) { + mAppId = appId; + SocketConfig.instance() + .setAppContext( context.getApplicationContext() ) + .setEnvironment( getEnvironment() ) + .setClient( Platform.getClient( Platform.car ) ) + .setChannelId( BaseServicesConstants.SOCKET_CHANNEL_ID ) + .setOpenAnalytics( true ) + .setSn( Utils.getSn() ) + .setDebug( DebugConfig.isDebug() ); + SocketMessageDispatcher.getInstance().start( context ); + } + + private Environment getEnvironment() { + switch ( DebugConfig.getNetMode() ) { + case 1: + return Environment.dev; + case 2: + case 4: + return Environment.qa; + case 3: + default: + return Environment.release; + } + } + + @Override + public void update( @NonNull CallbackManager manager, @NonNull byte[] content, String appId, long msgId ) { + try { + MogoConnsvr.Payload payload = MogoConnsvr.Payload.parseFrom( content ); + int msgType = payload.getMsgType(); + Logger.d( TAG, "received msg type = %d", msgType ); + List< IMogoOnMessageListener > listeners = mListeners.get( msgType ); + if ( listeners != null && !listeners.isEmpty() ) { + Iterator< IMogoOnMessageListener > iterator = listeners.iterator(); + if ( msgId != 0 ) { //兼容老版本 + if ( mReceivedMsgId.contains( msgId ) ) { // 避免消息重发 + return; + } + cacheLastReceivedMsgId( msgId ); + } + Object object = null; + while ( iterator.hasNext() ) { + IMogoOnMessageListener listener = iterator.next(); + if ( object == null ) { + object = GsonUtil.objectFromJson( payload.getPayload().toStringUtf8(), listener.target() ); + } + if ( listener != null ) { + Logger.d( TAG, "received msgId = %s, content = %s", msgId, payload.getPayload().toStringUtf8() ); + listener.onMsgReceived( object ); + } + } + } + } catch ( InvalidProtocolBufferException e ) { + Logger.e( TAG, e, "parse msg error." ); + } + } + + @Override + public void onAck( @NonNull CallbackManager manager, @NonNull byte[] headerBytes, byte[] content ) { + try { + MogoConnsvr.Header header = MogoConnsvr.Header.parseFrom( headerBytes ); + int msgType = header.getMsgType(); + String appId = header.getAppId(); + int productLine = header.getProductLine(); + long msgId = header.getMsgId(); + IMogoMsgAckListener listener = mAckListeners.remove( msgId ); + if ( listener != null ) { + listener.onAck( msgId ); + } + Logger.d( TAG, "send message success: msgType = %d, appId = %s, productLine = %d", msgType, appId, productLine ); + } catch ( InvalidProtocolBufferException e ) { + e.printStackTrace(); + } + } + + private void cacheLastReceivedMsgId( long msgId ) { + if ( msgId == 0 ) { + return; + } + synchronized ( this ) { + mReceivedMsgId.add( mCurrentIndex % MAX_CAP, msgId ); + mCurrentIndex++; + } + } + + @Override + public void registerOnMessageListener( int msgType, IMogoOnMessageListener listener ) { + if ( mListeners.containsKey( msgType ) ) { + Logger.w( TAG, "msgType %d is exist.", msgType ); + } + if ( !mListeners.containsKey( msgType ) ) { + mListeners.put( msgType, new ArrayList< IMogoOnMessageListener >() ); + } + mListeners.get( msgType ).add( listener ); + } + + @Override + public void unregisterOnMessageListener( int msgType ) { + mListeners.remove( msgType ); + } + + @Override + public void unregisterOnMessageListener( int msgType, IMogoOnMessageListener listener ) { + if ( listener == null ) { + return; + } + if ( !mListeners.containsKey( msgType ) ) { + return; + } + List< IMogoOnMessageListener > listeners = mListeners.get( msgType ); + if ( listeners != null && listeners.contains( listener ) ) { + listeners.remove( listener ); + } + } + + @Override + public void sendMsg( MsgBody body, IMogoMsgAckListener listener ) { + Logger.d( TAG, "sendMsg." ); + final byte[] pb = convertToPBBytes( body.getMsgType(), objectToBytes( body.getContent() ) ); + RequestUtil.sendPayloadData( mAppId, 2, pb, 1, true, System.currentTimeMillis() ); + } + + public byte[] objectToBytes( Object obj ) { + String jsonStr = GsonUtil.jsonFromObject( obj ); + return jsonStr.getBytes(); + } + + private byte[] convertToPBBytes( int msgType, byte[] payloadBytes ) { + MogoConnsvr.Payload payloadData = MogoConnsvr.Payload.newBuilder() + .setMsgType( msgType ) + .setPayload( ByteString.copyFrom( payloadBytes ) ).build(); + return payloadData.toByteArray(); + } + + public synchronized void release() { + mListeners.clear(); + mListeners = null; + sInstance = null; + } + + + @Override + public void init( Context context ) { + } + +} diff --git a/services/mogo-service-api/src/test/java/com/mogo/service/map/ExampleUnitTest.java b/foudations/mogo-base-services-sdk/src/test/java/com/mogo/base/services/ExampleUnitTest.java similarity index 91% rename from services/mogo-service-api/src/test/java/com/mogo/service/map/ExampleUnitTest.java rename to foudations/mogo-base-services-sdk/src/test/java/com/mogo/base/services/ExampleUnitTest.java index 6c7fa71433..ec74ef013f 100644 --- a/services/mogo-service-api/src/test/java/com/mogo/service/map/ExampleUnitTest.java +++ b/foudations/mogo-base-services-sdk/src/test/java/com/mogo/base/services/ExampleUnitTest.java @@ -1,4 +1,4 @@ -package com.mogo.service.map; +package com.mogo.base.services; import org.junit.Test; diff --git a/foudations/mogo-commons/apipackage.txt b/foudations/mogo-commons/apipackage.txt new file mode 100644 index 0000000000..855b249c77 --- /dev/null +++ b/foudations/mogo-commons/apipackage.txt @@ -0,0 +1,4 @@ +com.mogo.commons.mvp +com.mogo.commons.debug +com.mogo.commons.voice +com.mogo.commons.data \ No newline at end of file diff --git a/foudations/mogo-commons/build.gradle b/foudations/mogo-commons/build.gradle index 351e0d375c..0f2fc4036c 100644 --- a/foudations/mogo-commons/build.gradle +++ b/foudations/mogo-commons/build.gradle @@ -1,18 +1,23 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 29 - buildToolsVersion "29.0.2" - - + compileSdkVersion rootProject.ext.android.compileSdkVersion + // buildToolsVersion rootProject.ext.android.buildToolsVersion defaultConfig { - minSdkVersion 19 - targetSdkVersion 29 - versionCode 1 - versionName "1.0" + minSdkVersion rootProject.ext.android.minSdkVersion + targetSdkVersion rootProject.ext.android.targetSdkVersion + versionCode Integer.valueOf(VERSION_CODE) + versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION") testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' + + javaCompileOptions { + annotationProcessorOptions { + arguments = [AROUTER_MODULE_NAME: project.getName()] + } + } + } buildTypes { @@ -22,10 +27,31 @@ android { } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) api rootProject.ext.dependencies.aiassist - implementation project(":foudations:mogo-utils") + api rootProject.ext.dependencies.aiassistReplace + api rootProject.ext.dependencies.androidxappcompat + 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 + } else { + implementation project(":foudations:mogo-utils") + } + api 'org.greenrobot:eventbus:3.1.1' + + } + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() \ No newline at end of file diff --git a/foudations/mogo-commons/consumer-rules.pro b/foudations/mogo-commons/consumer-rules.pro index e69de29bb2..e4e113ccaf 100644 --- a/foudations/mogo-commons/consumer-rules.pro +++ b/foudations/mogo-commons/consumer-rules.pro @@ -0,0 +1,6 @@ +#-----Foundation-Commons----- +-keep class com.mogo.commons.data.BaseData.*{*;} +-keep class com.mogo.commons.voice.VoiceIntentTrack +-keep class com.mogo.commons.voice.VoiceTrack +-keep class com.mogo.commons.voice.VoicePreemptType +-keep interface * implements com.mogo.commons.mvp.IView \ No newline at end of file diff --git a/foudations/mogo-commons/gradle.properties b/foudations/mogo-commons/gradle.properties new file mode 100644 index 0000000000..7d5d7bf99b --- /dev/null +++ b/foudations/mogo-commons/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.commons +POM_ARTIFACT_ID=mogo-commons +VERSION_CODE=1 diff --git a/foudations/mogo-commons/proguard-rules.pro b/foudations/mogo-commons/proguard-rules.pro index f1b424510d..c47b3c8771 100644 --- a/foudations/mogo-commons/proguard-rules.pro +++ b/foudations/mogo-commons/proguard-rules.pro @@ -19,3 +19,10 @@ # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile + +#-----Foundation-Commons----- +-keep class com.mogo.commons.data.BaseData.*{*;} +-keep class com.mogo.commons.voice.VoiceIntentTrack +-keep class com.mogo.commons.voice.VoiceTrack +-keep class com.mogo.commons.voice.VoicePreemptType +-keep interface * implements com.mogo.commons.mvp.IView \ No newline at end of file diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/AbsMogoApplication.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/AbsMogoApplication.java index eeb155ead3..360dbb622b 100644 --- a/foudations/mogo-commons/src/main/java/com/mogo/commons/AbsMogoApplication.java +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/AbsMogoApplication.java @@ -1,6 +1,34 @@ package com.mogo.commons; import android.app.Application; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; + +import com.alibaba.android.arouter.launcher.ARouter; +import com.elegant.analytics.Analytics; +import com.elegant.analytics.AnalyticsConfig; +import com.mogo.commons.debug.DebugConfig; +import com.mogo.commons.device.Devices; +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.ThreadPoolService; +import com.mogo.utils.TipToast; +import com.mogo.utils.network.NetConfig; + +import java.io.IOException; +import java.security.SecureRandom; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; /** * @author congtaowang @@ -10,15 +38,100 @@ import android.app.Application; */ public class AbsMogoApplication extends Application { + private static final String TAG = "AbsMogoApplication"; + private static Application sApp; + public static Application getApp() { + return sApp; + } + @Override public void onCreate() { super.onCreate(); sApp = this; + init(); } - public static Application getApp() { - return sApp; + protected void init() { + syncInit(); + asyncInit(); + } + + private void syncInit() { + // 初始化 arouter + if ( DebugConfig.isDebug() ) { + ARouter.openDebug(); + ARouter.openLog(); + } + ARouter.init( sApp ); + TipToast.init( this, ( ( context, message ) -> { + if ( TextUtils.isEmpty( message ) ) { + return null; + } + View contentView = LayoutInflater.from( context ).inflate( R.layout.module_commons_layout_toast, null ); + TextView txt = contentView.findViewById( R.id.module_commons_toast_msg ); + txt.setText( message ); + return contentView; + } ) ); + } + + /** + * 忽略 https 验证 + * + * @return + * @throws Exception + */ + private static SSLContext getSslContext() throws Exception { + SSLContext sc = null; + sc = SSLContext.getInstance( "SSL" ); + sc.init( null, new TrustManager[]{new X509TrustManagerImpl()}, new SecureRandom() ); + return sc; + } + + private void asyncInit() { + ThreadPoolService.execute( () -> { + initNetConfig(); + // 初始化toast + // 初始化埋点 + Analytics.getInstance().start( sApp ); + Analytics.getInstance().setAppKey( "6bbe7e0e1ecd8e2f8dc336e1678a2791" ); + // 0 - debug 近实时上报,积累一条埋点上报,或者积累3秒上报一次。 + // 2 - 本地缓存,聚合上报,积累30条埋点上报,或者积累60秒上报一次。 + AnalyticsConfig.getInstance( sApp ).setMode( DebugConfig.isDebug() ? 0 : 2 ); + AnalyticsConfig.getInstance( sApp ).shouldLog( DebugConfig.isDebug() ); + Devices.init( getApp() ); + Devices.checkBindState(); + asyncInitImpl(); + } ); + } + + protected void asyncInitImpl(){ + + } + + private static void initNetConfig() { + + try { + SSLContext sc = getSslContext(); + NetConfig.instance().setSslContext( sc ); + } catch ( Exception e ) { + } + + NetConfig.instance().setSignaturePrefix( Constants.SIGN_PREFIX ) + .setPublicParams( ParamsUtil.getStaticParams() ) + .setHostnameVerifier( new AllAllowedHostnameVerifier() ) + .addNetworkInterceptor( new Interceptor() { + @Override + public Response intercept( Chain chain ) throws IOException { + Request original = chain.request(); + Request request = original.newBuilder() + .header( "token", SpStorage.getTicket() ) + .method( original.method(), original.body() ) + .build(); + return chain.proceed( request ); + } + } ) + .setLoggable( DebugConfig.isDebug() ); } } diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/analytics/AnalyticsUtils.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/analytics/AnalyticsUtils.java new file mode 100644 index 0000000000..599f0271ae --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/analytics/AnalyticsUtils.java @@ -0,0 +1,26 @@ +package com.mogo.commons.analytics; + +import com.elegant.analytics.Analytics; +import com.mogo.commons.network.ParamsUtil; + +import java.util.Map; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * 埋点 + */ +public class AnalyticsUtils { + + /** + * 埋点 + * + * @param event 事件名称 + * @param properties 事件参数 + */ + public static void track( String event, Map< String, Object > properties ) { + Analytics.getInstance().setCustomParams( ParamsUtil.getAnalyticsCustomParams() ); + Analytics.getInstance().track( event, properties ); + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/debug/DebugConfig.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/debug/DebugConfig.java new file mode 100644 index 0000000000..fff915fbb3 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/debug/DebugConfig.java @@ -0,0 +1,240 @@ +package com.mogo.commons.debug; + +import com.mogo.utils.logger.Logger; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * 各个模块递调试信息控制接口 + *

+ * 注:该类已经不再是简单的调试配置,已经涉及到功能逻辑了 囧 + */ +public class DebugConfig { + + private static boolean sDebug = true; + + /** + * 是否为调试模式 + * + * @return true - 调试模式 false - 非调试模式 + */ + public static boolean isDebug() { + return sDebug; + } + + /** + * 设置调试模式 + * + * @param sDebug true - 调试模式 false - 非调试模式 + */ + 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_DEMO = 4; + + /** + * 生产环境 + */ + public static final int NET_MODE_RELEASE = 3; + + + private static int sNetMode = NET_MODE_RELEASE; + + /** + * 不使用语音助手 + */ + public static final int AI_TYPE_NOOP = 0; + + /** + * 语音使用同行者 + */ + public static final int AI_TYPE_TXZ = 1; + /** + * 语音使用思必驰 + */ + public static final int AI_TYPE_SPEECH = 2; + + private static int sAIType = AI_TYPE_TXZ; + + /** + * 自研车机 + */ + public static final int CAR_MACHINE_TYPE_SELF_INNOVATE = 0; + + /** + * 比亚迪的车机 + */ + public static final int CAR_MACHINE_TYPE_BYD = 1; + + private static int sCarMachineType = CAR_MACHINE_TYPE_SELF_INNOVATE; + + /** + * 获取网络环境类型 + * + * @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_DEMO} + * {@link #NET_MODE_RELEASE} + */ + public static void setNetMode( int netMode ) { + DebugConfig.sNetMode = netMode; + } + + /** + * 是否拉起位置服务,launcher 需要拉起位置服务,独立 app 不需要 + */ + private static boolean sLaunchLocationService = true; + + public static boolean isLaunchLocationService() { + return sLaunchLocationService; + } + + public static void setLaunchLocationService( boolean launchLocationService ) { + DebugConfig.sLaunchLocationService = launchLocationService; + } + + /** + * 是否使用自定义导航 + */ + private static boolean sUseCustomNavi = false; + + public static boolean isUseCustomNavi() { + return sUseCustomNavi; + } + + public static void setUseCustomNavi( boolean sUseCustomNavi ) { + DebugConfig.sUseCustomNavi = sUseCustomNavi; + } + + /** + * 设置使用哪个语音助手 + * + * @param aiType {@link #AI_TYPE_NOOP} {@link #AI_TYPE_TXZ} {@link #AI_TYPE_SPEECH} + */ + public static void setAIType( int aiType ) { + Logger.d( "DebugConfig", "setAiType: " + aiType ); + sAIType = aiType; + } + + /** + * 使用哪个语音助手 {@link #AI_TYPE_NOOP} {@link #AI_TYPE_TXZ} {@link #AI_TYPE_SPEECH} + */ + public static int getAIType() { + return sAIType; + } + + /** + * 设置当前车机类型 + * + * @param type {@link #CAR_MACHINE_TYPE_SELF_INNOVATE} {@link #CAR_MACHINE_TYPE_BYD} + */ + public static void setCarMachineType( int type ) { + sCarMachineType = type; + } + + /** + * 获取当前车机类型 + * + * @return {@link #CAR_MACHINE_TYPE_SELF_INNOVATE} {@link #CAR_MACHINE_TYPE_BYD} + */ + public static int getCarMachineType() { + return sCarMachineType; + } + + /** + * 是否作为launcher运行 + */ + private static boolean sIsLauncher = false; + + public static boolean isLauncher() { + return sIsLauncher; + } + + public static void setLauncher( boolean isLauncher ) { + DebugConfig.sIsLauncher = isLauncher; + } + + private static boolean sRequestOnlineCarData = true; + + public static boolean isRequestOnlineCarData() { + return sRequestOnlineCarData; + } + + public static void setRequestOnlineCarData( boolean sRequestOnlineCarData ) { + DebugConfig.sRequestOnlineCarData = sRequestOnlineCarData; + } + + /** + * 是否支持临时激活小智 + */ + private static boolean sActiveAIAssistFlag = true; + + public static boolean isActiveAIAssistFlag() { + return sActiveAIAssistFlag; + } + + public static void setActiveAIAssistFlag( boolean sActiveAIAssistFlag ) { + DebugConfig.sActiveAIAssistFlag = sActiveAIAssistFlag; + } + + private static boolean useMockObuData; + + public static void setUseMockObuData( boolean use ) { + useMockObuData = use; + } + + public static boolean isUseMockObuData() { + return useMockObuData; + } + + private static String sProductFlavor; + + public static String getProductFlavor() { + return sProductFlavor; + } + + /** + * 产品线 + * + * @param sProductFlavor + */ + public static void setProductFlavor( String sProductFlavor ) { + DebugConfig.sProductFlavor = sProductFlavor; + } + + private static String sSocketAppId; + + public static void setSocketAppId( String sSocketAppId ) { + DebugConfig.sSocketAppId = sSocketAppId; + } + + public static String getSocketAppId() { + return sSocketAppId; + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/device/Devices.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/device/Devices.java new file mode 100644 index 0000000000..56eaa84ac1 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/device/Devices.java @@ -0,0 +1,71 @@ +package com.mogo.commons.device; + +import android.content.ContentResolver; +import android.content.Context; +import android.database.ContentObserver; +import android.database.Cursor; +import android.net.Uri; + +import com.mogo.commons.AbsMogoApplication; +import com.mogo.utils.ThreadPoolService; +import com.mogo.utils.logger.Logger; + +public +/** + * @author congtaowang + * @since 2020/6/8 + * + * 描述 + */ +class Devices { + + private static final String TAG = "Devices"; + + public static final Uri CONTENT_URI_BIND = Uri.parse( "content://com.zhidao.guide.lock.product.bindstatus/status" ); + + private static boolean sIsBind = false; + + public static void init( Context context ) { + if ( context == null ) { + return; + } + context.getContentResolver().registerContentObserver( CONTENT_URI_BIND, true, new ContentObserver( null ) { + @Override + public void onChange( boolean selfChange ) { + super.onChange( selfChange ); + ThreadPoolService.execute( () -> { + checkBindState(); + Logger.d( TAG, "lock status changed. the last val = " + sIsBind ); + } ); + } + } ); + } + + /** + * 检测车机激活状态 + * + * @return + */ + public static boolean checkBindState() { + try { + ContentResolver resolver = AbsMogoApplication.getApp().getContentResolver(); + if ( resolver == null ) { + return false; + } + try ( Cursor cursor = resolver.query( CONTENT_URI_BIND, null, null, null, null ) ) { + if ( cursor == null || !cursor.moveToFirst() ) { + return false; + } + int status = cursor.getInt( cursor.getColumnIndex( "lock_status" ) ); + return sIsBind = ( status == 1 ); + } + } catch ( Exception e ) { + e.printStackTrace(); + } + return false; + } + + public static boolean isBind() { + return sIsBind; + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/IView.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/IView.java new file mode 100644 index 0000000000..f536b95f88 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/IView.java @@ -0,0 +1,19 @@ +package com.mogo.commons.mvp; + +import android.content.Context; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * mvp的view接口 + */ +public interface IView { + + /** + * 获取上下文 + * + * @return + */ + Context getContext(); +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/MvpActivity.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/MvpActivity.java new file mode 100644 index 0000000000..c31eb8b869 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/MvpActivity.java @@ -0,0 +1,92 @@ +package com.mogo.commons.mvp; + +import android.content.Context; +import android.os.Bundle; + +import android.view.MotionEvent; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.mogo.commons.debug.DebugConfig; +import com.mogo.utils.SoftKeyBoardJobber; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * mvp 的 activity + */ +public abstract class MvpActivity< V extends IView, P extends Presenter< V > > + extends AppCompatActivity implements IView { + + protected P mPresenter; + + @Override + protected void onCreate( @Nullable Bundle savedInstanceState ) { + super.onCreate( savedInstanceState ); + if (DebugConfig.getCarMachineType() == DebugConfig.CAR_MACHINE_TYPE_BYD) { + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + setContentView( getLayoutId() ); + initViews(); + mPresenter = createPresenter(); + getLifecycle().addObserver( mPresenter ); + } + + /** + * 布局资源 + * + * @return 布局资源 id + */ + protected abstract int getLayoutId(); + + /** + * 初始化控件,必须在初始化完成之后才可以实例化presenter,避免 + * presenter 生命周期错乱 + */ + protected abstract void initViews(); + + /** + * 创建 presenter 实例 + * + * @return + */ + @NonNull + protected abstract P createPresenter(); + + @Override + public Context getContext() { + return this; + } + + @Override + public boolean dispatchTouchEvent( MotionEvent ev ) { + if ( ev.getAction() == MotionEvent.ACTION_DOWN && enableDispatchTouchEventToDismissSoftKeyBoard() ) { + SoftKeyBoardJobber.hideIfNecessary( this, ev ); + return super.dispatchTouchEvent( ev ); + } + // 必不可少,否则所有的组件都不会有TouchEvent了 + if ( getWindow().superDispatchTouchEvent( ev ) ) { + return true; + } + return onTouchEvent( ev ); + } + protected boolean enableDispatchTouchEventToDismissSoftKeyBoard() { + return true; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + getLifecycle().removeObserver( mPresenter ); + if ( mPresenter != null ) { + getLifecycle().removeObserver( mPresenter ); + } + mPresenter = null; + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/MvpDialogFragment.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/MvpDialogFragment.java new file mode 100644 index 0000000000..bcd2e6412a --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/MvpDialogFragment.java @@ -0,0 +1,106 @@ +package com.mogo.commons.mvp; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.Fragment; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * mvp fragment + */ +public abstract class MvpDialogFragment< V extends IView, P extends Presenter< V > > extends DialogFragment implements IView { + + private Context mContext; + protected P mPresenter; + protected View mRootView; + + @Override + public void onAttach( Context context ) { + super.onAttach( context ); + mContext = context; + } + + @Nullable + @Override + public View onCreateView( @NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState ) { + if ( mRootView == null ) { + mRootView = inflater.inflate( getLayoutId(), container, false ); + } else { + ViewGroup viewGroup = ( ViewGroup ) mRootView.getParent(); + if ( viewGroup != null ) + viewGroup.removeView( mRootView ); + } + return mRootView; + } + + @Override + public void onViewCreated( @NonNull View view, @Nullable Bundle savedInstanceState ) { + super.onViewCreated( view, savedInstanceState ); + } + + /** + * 布局资源 + * + * @return + */ + protected abstract int getLayoutId(); + + @Override + public void onActivityCreated( @Nullable Bundle savedInstanceState ) { + super.onActivityCreated( savedInstanceState ); + initViews(); + mPresenter = createPresenter(); + getViewLifecycleOwner().getLifecycle().addObserver( mPresenter ); + } + + /** + * 初始化控件,必须在初始化完成之后才可以实例化presenter,避免 + * presenter 生命周期错乱 + */ + protected abstract void initViews(); + + /** + * 创建 presenter 实例 + * + * @return + */ + @NonNull + protected abstract P createPresenter(); + + @Nullable + protected < T extends View > T findViewById( int id ) { + if ( mRootView != null ) { + return ( T ) mRootView.findViewById( id ); + } + return null; + } + + @Nullable + @Override + public Context getContext() { + if ( mContext == null ) { + mContext = super.getContext(); + } + return mContext; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if ( mPresenter != null ) { + getViewLifecycleOwner().getLifecycle().removeObserver( mPresenter ); + } + mPresenter = null; + mRootView = null; + mContext = null; + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/MvpFragment.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/MvpFragment.java new file mode 100644 index 0000000000..3561592a54 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/MvpFragment.java @@ -0,0 +1,115 @@ +package com.mogo.commons.mvp; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; + +import com.mogo.utils.logger.Logger; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * mvp fragment + */ +public abstract class MvpFragment> extends Fragment implements IView { + + private Context mContext; + protected P mPresenter; + protected View mRootView; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + mContext = context; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + if ( mRootView == null ) { + mRootView = inflater.inflate( getLayoutId(), container, false ); + } else { + ViewGroup viewGroup = ( ViewGroup ) mRootView.getParent(); + if ( viewGroup != null ) + viewGroup.removeView( mRootView ); + } + mRootView = inflater.inflate(getLayoutId(), container, false); + return mRootView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + initViews(savedInstanceState); + } + + /** + * 布局资源 + * + * @return + */ + protected abstract int getLayoutId(); + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + initViews(); + mPresenter = createPresenter(); + getViewLifecycleOwner().getLifecycle().addObserver(mPresenter); + } + + /** + * 初始化控件,必须在初始化完成之后才可以实例化presenter,避免 + * presenter 生命周期错乱 + */ + protected abstract void initViews(); + + protected void initViews(Bundle savedInstanceState) { + } + + /** + * 创建 presenter 实例 + * + * @return + */ + @NonNull + protected abstract P createPresenter(); + + @Nullable + protected T findViewById(int id) { + if (mRootView == null) { + mRootView = getView().findViewById(id); + } + if (mRootView != null) { + return (T) mRootView.findViewById(id); + } + return null; + } + + @Nullable + @Override + public Context getContext() { + if (mContext == null) { + mContext = super.getContext(); + } + return mContext; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if (mPresenter != null) { + getViewLifecycleOwner().getLifecycle().removeObserver(mPresenter); + } + mPresenter = null; + mRootView = null; + mContext = null; + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/Presenter.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/Presenter.java new file mode 100644 index 0000000000..a4942158e5 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/mvp/Presenter.java @@ -0,0 +1,92 @@ +package com.mogo.commons.mvp; + +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.os.Build; +import android.view.View; +import android.widget.PopupWindow; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleObserver; +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.OnLifecycleEvent; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * mvp 的 presenter + */ +public abstract class Presenter< V extends IView > implements LifecycleObserver { + + protected V mView; + private Context mContext; + + public Presenter( V view ) { + this.mView = view; + } + + @OnLifecycleEvent( Lifecycle.Event.ON_CREATE ) + public void onCreate( @NonNull LifecycleOwner owner ) { + } + + @OnLifecycleEvent( Lifecycle.Event.ON_START ) + public void onStart( @NonNull LifecycleOwner owner ) { + } + + @OnLifecycleEvent( Lifecycle.Event.ON_RESUME ) + public void onResume( @NonNull LifecycleOwner owner ) { + } + + @OnLifecycleEvent( Lifecycle.Event.ON_PAUSE ) + public void onPause( @NonNull LifecycleOwner owner ) { + } + + @OnLifecycleEvent( Lifecycle.Event.ON_STOP ) + public void onStop( @NonNull LifecycleOwner owner ) { + } + + @OnLifecycleEvent( Lifecycle.Event.ON_DESTROY ) + public void onDestroy( @NonNull LifecycleOwner owner ) { + } + + @OnLifecycleEvent( Lifecycle.Event.ON_ANY ) + public void onLifecycleChanged( + @NonNull LifecycleOwner owner, + @NonNull Lifecycle.Event event ) { + } + + protected Context getContext() { + if ( mContext != null ) { + return mContext; + } + if ( mView instanceof Activity ) { + mContext = ( ( Activity ) mView ); + } + if ( mView instanceof Fragment ) { + mContext = ( ( Fragment ) mView ).getContext(); + } + if ( mView instanceof android.app.Fragment ) { + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) { + mContext = ( ( android.app.Fragment ) mView ).getContext(); + } else { + mContext = ( ( android.app.Fragment ) mView ).getActivity(); + } + } + if ( mView instanceof Dialog ) { + mContext = ( ( Dialog ) mView ).getContext(); + } + if ( mView instanceof PopupWindow ) { + if ( ( ( PopupWindow ) mView ).getContentView() != null ) { + mContext = ( ( PopupWindow ) mView ).getContentView().getContext(); + } + } + if ( mView instanceof View ) { + mContext = ( ( View ) mView ).getContext(); + } + return mContext; + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/network/Constants.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/Constants.java new file mode 100644 index 0000000000..9597a405b2 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/Constants.java @@ -0,0 +1,27 @@ +package com.mogo.commons.network; + +public interface Constants { + + String UTF_8 = "UTF-8"; + + String KEY_PHONE = "user_phone"; + String KEY_TOKEN = "user_token "; + String KEY_USER_ID = "userId"; + String KEY_DISPLAY_NAME = "displayName"; + String KEY_SN = "sn"; + + String OS = "Android-Car"; + + String KEY_SOURCE = ServerParam.SOURCE; + String DEFAULT_SOURCE = "appLauncher"; + + // 车机已绑定状态 + int STATUS_BIND = 1; + + String KEY_TICKET = "ticket"; + + /** + * sign,salt + */ + String SIGN_PREFIX = "JGjZx6"; +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/network/HttpParamsEx.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/HttpParamsEx.java new file mode 100644 index 0000000000..59d3043332 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/HttpParamsEx.java @@ -0,0 +1,27 @@ +package com.mogo.commons.network; + +import android.text.TextUtils; + +import com.mogo.utils.logger.Logger; +import com.mogo.utils.network.BaseParams; +import com.mogo.utils.network.HttpParams; + + +/** + * Created by congtaowang on 2018/10/21. + */ +public class HttpParamsEx extends HttpParams { + + private static final String TAG = "HttpParamsEx"; + + @Override + public BaseParams put( String key, Object value ) { + + if ( !TextUtils.isEmpty( key ) ) { + if ( value == null ) { + Logger.e( TAG, "%s with illegal value", key ); + } + } + return super.put( key, value ); + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/network/LocationHelper.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/LocationHelper.java new file mode 100644 index 0000000000..87aea86ff0 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/LocationHelper.java @@ -0,0 +1,39 @@ +package com.mogo.commons.network; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author congtaowang + * @since 2020-01-02 + *

+ * 缓存当前经纬度位置,便于接口请求 + */ +public class LocationHelper { + + private static volatile LocationHelper sInstance; + + private LocationHelper() { + } + + public static LocationHelper getInstance() { + if ( sInstance == null ) { + synchronized ( LocationHelper.class ) { + if ( sInstance == null ) { + sInstance = new LocationHelper(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + private Map< String, Object > mLocationProperties = new HashMap<>(); + + public synchronized Map< String, Object > getLocationProperties() { + return mLocationProperties; + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/network/ParamsProvider.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/ParamsProvider.java new file mode 100644 index 0000000000..c09ad6d2f1 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/ParamsProvider.java @@ -0,0 +1,72 @@ +package com.mogo.commons.network; + +import android.content.Context; + +import com.mogo.utils.CheckUtils; +import com.mogo.utils.network.HttpParams; +import com.mogo.utils.network.NetConfig; +import com.mogo.utils.network.ServerParam; +import com.mogo.utils.network.utils.SignUtil; + +import java.util.Map; +import java.util.Set; + +public class ParamsProvider { + + private static Map< String, Object > getParams( Context context ) { + return getParams( context, new HttpParams(), Constants.SIGN_PREFIX ); + } + + private static Map< String, Object > getParams( Context context, HttpParams httpParams, String salt ) { + final Map< String, Object > publicParams = NetConfig.instance().getPublicParams(); + if ( !CheckUtils.isEmpty( publicParams ) ) { + for ( Map.Entry< String, Object > entry : publicParams.entrySet() ) { + httpParams.put( entry.getKey(), entry.getValue() ); + } + } + + final Map< String, Object > dynamicParams = ParamsUtil.getDynamicParams(); + if ( !CheckUtils.isEmpty( dynamicParams ) ) { + for ( Map.Entry< String, Object > entry : dynamicParams.entrySet() ) { + httpParams.put( entry.getKey(), entry.getValue() ); + } + } + + httpParams.put( ServerParam.SIGNATURE, SignUtil.createSign( httpParams.getParamsMap(), salt ) ); + return httpParams.getParamsMap(); + } + + public static final class Builder { + private HttpParams mHttpParams; + private Context mContext; + + public Builder( Context context ) { + this.mHttpParams = new HttpParamsEx(); + this.mContext = context; + } + + public Builder append( String key, Object value ) { + mHttpParams.put( key, value ); + return this; + } + + public Builder append( Map< String, Object > keyValuePairs ) { + if ( keyValuePairs != null && !keyValuePairs.isEmpty() ) { + final Set< Map.Entry< String, Object > > entries = keyValuePairs.entrySet(); + for ( Map.Entry< String, Object > entry : entries ) { + this.append( entry.getKey(), entry.getValue() ); + } + } + return this; + } + + public Map< String, Object > build() { + return build( Constants.SIGN_PREFIX ); + } + + public Map< String, Object > build( String salt ) { + return getParams( mContext, mHttpParams, salt ); + } + } + +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/network/ParamsUtil.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/ParamsUtil.java new file mode 100644 index 0000000000..b6645fa28c --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/ParamsUtil.java @@ -0,0 +1,154 @@ +package com.mogo.commons.network; + +import android.os.Build; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.collection.ArrayMap; + +import com.mogo.commons.AbsMogoApplication; +import com.mogo.commons.debug.DebugConfig; +import com.mogo.commons.storage.SpStorage; +import com.mogo.utils.CommonUtils; +import com.mogo.utils.DeviceIdUtils; +import com.mogo.utils.WindowUtils; +import com.mogo.utils.logger.Logger; +import com.mogo.utils.network.utils.GsonUtil; +import com.zhidao.auto.platform.util.DeviceUtil; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Map; +import java.util.Set; + +import okhttp3.RequestBody; + +public class ParamsUtil { + + private static final String TAG = "ParamsUtil"; + + public static Map< String, Object > getDynamicParams() { + Map< String, Object > params = new ArrayMap(); + + final Map< String, Object > location = LocationHelper.getInstance().getLocationProperties(); + if ( location != null ) { + params.putAll( location ); + } + params.put( ServerParam.NET_TYPE, CommonUtils.getNetworkType( AbsMogoApplication.getApp() ) ); + params.put( ServerParam.CELL_ID, Utils.getCellId( AbsMogoApplication.getApp() ) ); + + params.put( ServerParam.DISPLAY_ID, DeviceUtil.getSystemVersion() ); + params.put( ServerParam.SN, Utils.getSn() ); + params.put( ServerParam.TICKET, SpStorage.getTicket() ); + + return params; + } + + private static final Map< String, Object > STATIC_PARAMS = new ArrayMap<>(); + + static { + STATIC_PARAMS.put( ServerParam.BRAND, Build.BRAND ); + STATIC_PARAMS.put( ServerParam.MANUFACTURER, Build.MANUFACTURER ); + STATIC_PARAMS.put( ServerParam.MODEL, Build.MODEL ); + STATIC_PARAMS.put( ServerParam.PRODUCT, Build.PRODUCT ); + STATIC_PARAMS.put( ServerParam.OS, Constants.OS ); + STATIC_PARAMS.put( ServerParam.OS_VERSION, Build.VERSION.RELEASE ); + STATIC_PARAMS.put( ServerParam.MOBILE_MODEL, CommonUtils.getModel() ); + STATIC_PARAMS.put( ServerParam.VERSION_CODE, CommonUtils.getVersionCode( AbsMogoApplication.getApp() ) ); + STATIC_PARAMS.put( ServerParam.VERSION_NAME, CommonUtils.getVersionName( AbsMogoApplication.getApp() ) ); + STATIC_PARAMS.put( ServerParam.SCREEN_PIXELS, WindowUtils.getScreenPixels( AbsMogoApplication.getApp() ) ); + STATIC_PARAMS.put( ServerParam.ANDROID_ID, CommonUtils.getAndroidID( AbsMogoApplication.getApp() ) ); + STATIC_PARAMS.put( ServerParam.DEVICE_ID, DeviceIdUtils.getDeviceId( AbsMogoApplication.getApp() ) ); + STATIC_PARAMS.put( ServerParam.IMEI, CommonUtils.getIMEI( AbsMogoApplication.getApp() ) ); + STATIC_PARAMS.put( ServerParam.IMSI, CommonUtils.getIMSI( AbsMogoApplication.getApp() ) ); + STATIC_PARAMS.put( ServerParam.END_POINT, ServerParam.END_POINT_CAR ); + } + + public static Map< String, Object > getStaticParams() { + return STATIC_PARAMS; + } + + public static Map< String, Object > getAnalyticsCustomParams() { + Map< String, Object > map = new ArrayMap<>(); + map.put( "debug", DebugConfig.isDebug() ? 1 : 0 ); + String fota = Utils.getFotaVersion(); + map.put( "systemversion", TextUtils.isEmpty( fota ) ? DebugConfig.getProductFlavor() : fota ); + map.put( "sn", Utils.getSn() ); + return map; + } + + public static RequestBody convert( Map< String, Object > map ) { + String json = GsonUtil.getGson().toJson( map ); + Logger.d( TAG, "request params: %s", json ); + RequestBody requestBody = RequestBody.create( okhttp3.MediaType.parse( "application/json; charset=utf-8" ), json ); + return requestBody; + } + + /** + * post 请求only + * + * @param url 地址 + * @param params 参数 (公共+业务+签名) + * @param businessParams query 串中不需要保留的参数,一般为业务参数 + * @return + */ + public static String toQueryUrl( @NonNull String url, Map< String, Object > params, Map< String, Object > businessParams ) { + + if ( TextUtils.isEmpty( url ) ) { + return url; + } + + params = diff( params, businessParams ); + if ( params == null || params.isEmpty() ) { + return url; + } + final Set< String > keys = params.keySet(); + StringBuilder builder = new StringBuilder(); + for ( String key : keys ) { + if ( TextUtils.isEmpty( key ) ) { + Logger.w( TAG, "key is illegal" ); + continue; + } + + final Object value = params.get( key ); + if ( value == null ) { + Logger.w( TAG, "%s - value is illegal", key ); + continue; + } + String targetValue = value.toString(); + try { + targetValue = URLEncoder.encode( targetValue, "utf-8" ); + } catch ( UnsupportedEncodingException e ) { + targetValue = value.toString(); + } + builder.append( key ).append( "=" ).append( targetValue ).append( "&" ); + } + String queryString = builder.toString(); + if ( queryString.endsWith( "&" ) ) { + queryString = queryString.substring( 0, queryString.length() - 1 ); + } + + if ( !url.endsWith( "?" ) ) { + url += "?"; + } + return url + queryString; + } + + /** + * @param parent 全部参数 + * @param child 业务参数 + * @return + */ + public static Map< String, Object > diff( Map< String, Object > parent, Map< String, Object > child ) { + if ( parent == null || parent.isEmpty() || child == null || child.isEmpty() ) { + return parent; + } + for ( String key : child.keySet() ) { + if ( TextUtils.isEmpty( key ) || TextUtils.equals( "extra_id", key ) ) { + continue; + } + parent.remove( key ); + } + return parent; + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/network/ServerParam.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/ServerParam.java new file mode 100644 index 0000000000..b7f699f297 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/ServerParam.java @@ -0,0 +1,45 @@ +package com.mogo.commons.network; + +class ServerParam { + + public static final String LAT = "lat"; + public static final String LNG = "lng"; + public static final String CITY_CODE = "cityCode"; + public static final String AD_CODE = "adCode"; + public static final String SELECTED_AD_CODE = "selectedAdCode"; + + // 用户名 + public static final String DISPLAY_NAME = "displayName"; + + public static final String OS = "os"; + public static final String BRAND = "brand"; + public static final String MANUFACTURER = "manufacturer"; + public static final String MODEL = "model"; + public static final String OS_VERSION = "osVersion"; + public static final String PRODUCT = "product"; + // 系统版本号 + public static final String DISPLAY_ID = "displayId"; + + public static final String MOBILE_MODEL = "hardWareModel"; + public static final String CELL_ID = "cellId"; + public static final String IMEI = "imei"; + public static final String IMSI = "imsi"; + public static final String SOURCE = "source"; + public static final String NET_TYPE = "netType"; + public static final String VERSION_CODE = "appVersionCode"; + public static final String VERSION_NAME = "appVersion"; + public static final String SCREEN_PIXELS = "pixels"; + public static final String ANDROID_ID = "androidId"; + public static final String DEVICE_ID = "deviceId"; + public static final String SN = "sn"; + public static final String CHANNEL = "channel"; + + public static final String USER_ID = "userId"; + public static final String FILE = "file"; + public static final String END_POINT = "endPoint"; + public static final String END_POINT_CAR = "CAR"; + + public static final String PHONE = "phone"; + public static final String TICKET = "ticket"; + +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/network/SubscribeImpl.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/SubscribeImpl.java new file mode 100644 index 0000000000..5d9217849e --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/SubscribeImpl.java @@ -0,0 +1,78 @@ +package com.mogo.commons.network; + +import com.mogo.commons.data.BaseData; +import com.mogo.utils.logger.Logger; +import com.mogo.utils.network.RequestOptions; +import com.mogo.utils.network.utils.Util; + +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; + + +/** + * Created by congtaowang on 2018/10/14. + */ +public abstract class SubscribeImpl< T extends BaseData > implements Observer< T > { + + protected final RequestOptions mRequestOptions; + + private static final String TAG = "SubscribeImpl"; + private boolean mAutoTipMsg = true; + + public SubscribeImpl( RequestOptions requestOptions ) { + mRequestOptions = requestOptions; + } + + public SubscribeImpl( RequestOptions requestOptions, boolean autoTipMsg ) { + this( requestOptions ); + mAutoTipMsg = autoTipMsg; + } + + private void onFinish() { + if ( !Util.checkAlive( mRequestOptions.getCaller() ) ) { + } + } + + @Override + public void onError( Throwable e ) { + onFinish(); + Logger.e( TAG, e, "occur when net request." ); + } + + @Override + public void onNext( T o ) { + if ( o != null ) { + if ( o.code != 0 ) { + onError( o.msg, o.code ); + } else { + onSuccess( o ); + } + } else { + onError( "", -1 ); + } + } + + + @Override + public void onSubscribe( Disposable d ) { + + } + + @Override + public void onComplete() { + onFinish(); + } + + public void onSuccess( T o ) { + } + + public void onError( String message, int code ) { + Logger.e( TAG, "%d - %s", code, message ); + } + + private static boolean isTicketUpdated = false; + + private void onUpdateTicket() { + + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/network/Utils.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/Utils.java new file mode 100644 index 0000000000..90bc9e507d --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/network/Utils.java @@ -0,0 +1,98 @@ +package com.mogo.commons.network; + +import android.Manifest; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.telephony.CellLocation; +import android.telephony.TelephonyManager; +import android.telephony.cdma.CdmaCellLocation; +import android.telephony.gsm.GsmCellLocation; +import android.text.TextUtils; + +import com.mogo.commons.AbsMogoApplication; +import com.mogo.commons.debug.DebugConfig; +import com.mogo.utils.storage.SharedPrefsMgr; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Created by congtaowang on 2018/3/29. + */ + +public class Utils { + + public static String getCellId( Context context ) { + TelephonyManager tm = ( TelephonyManager ) context.getSystemService( Context.TELEPHONY_SERVICE ); + if ( tm == null ) { + return ""; + } + + PackageManager pm = context.getPackageManager(); + boolean accessCoarseLocationPermission = ( PackageManager.PERMISSION_GRANTED == + pm.checkPermission( Manifest.permission.ACCESS_COARSE_LOCATION, context.getPackageName() ) ); + boolean accessFineLocationPermission = ( PackageManager.PERMISSION_GRANTED == + pm.checkPermission( Manifest.permission.ACCESS_FINE_LOCATION, context.getPackageName() ) ); + if ( !accessCoarseLocationPermission || !accessFineLocationPermission ) + return "noPermission"; + + CellLocation location = null; + try { + location = tm.getCellLocation(); + } catch ( Exception e ) { + e.printStackTrace(); + } + if ( location != null ) { + // Gsm网络 , 联通移动的网络属于这一套 + if ( location instanceof GsmCellLocation ) { + GsmCellLocation gsmLoc = ( GsmCellLocation ) location; + int cellid = gsmLoc.getCid(); + return String.valueOf( cellid ); + // Cdma网络 , 电信网络属于这一种 + } else if ( location instanceof CdmaCellLocation ) { + CdmaCellLocation cdmaLoc = ( CdmaCellLocation ) location; + return String.valueOf( cdmaLoc.getBaseStationId() ); + } + } + return ""; + } + + + public static final String GET = "get"; + public static final String GSM_SERIAL = "gsm.serial"; + public static final String BYD_SERIAL = "ro.serialno"; + public static final String FOTA_VERSION = "ro.fota.version"; + public static final String PROPERTIES = "android.os.SystemProperties"; + + public static String getSn() { + + if ( DebugConfig.getCarMachineType() != DebugConfig.CAR_MACHINE_TYPE_SELF_INNOVATE ) { + return SharedPrefsMgr.getInstance( AbsMogoApplication.getApp() ).getString( "allocated_sn" ); + } + return getSystemProperties( GSM_SERIAL ); + } + + public static String getFotaVersion() { + return getSystemProperties( FOTA_VERSION ); + } + + public static String getSystemProperties( String name ) { + String value = ""; + + try { + Class< ? > c = Class.forName( PROPERTIES ); + Method get = c.getMethod( GET, String.class ); + value = ( String ) get.invoke( c, name ); + } catch ( ClassNotFoundException var3 ) { + var3.printStackTrace(); + } catch ( NoSuchMethodException var4 ) { + var4.printStackTrace(); + } catch ( InvocationTargetException var5 ) { + var5.printStackTrace(); + } catch ( IllegalAccessException var6 ) { + var6.printStackTrace(); + } + return value; + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/storage/SpStorage.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/storage/SpStorage.java new file mode 100644 index 0000000000..0fbca06a32 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/storage/SpStorage.java @@ -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 + *

+ * 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 ); + } +} diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/AIAssist.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/AIAssist.java index 7f50aeae8e..e752812148 100644 --- a/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/AIAssist.java +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/AIAssist.java @@ -1,11 +1,25 @@ package com.mogo.commons.voice; +import android.app.ActivityManager; import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.text.TextUtils; +import com.mogo.commons.AbsMogoApplication; +import com.mogo.utils.logger.Logger; import com.zhidao.auto.platform.voice.VoiceClient; +import com.zhidao.voicesdk.MogoVoiceManager; +import com.zhidao.voicesdk.MogoVoiceManagerImpl; +import com.zhidao.voicesdk.callback.OnConnStatusListener; +import com.zhidao.voicesdk.callback.OnTtsListener; +import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * @author congtaowang @@ -13,9 +27,14 @@ import java.util.Map; *

* 语音助手通信助手 */ -public class AIAssist implements VoiceClient.VoiceCmdCallBack { +public class AIAssist implements VoiceClient.VoiceCmdCallBack, OnTtsListener { + private static final String TAG = "AIAssist"; private static volatile AIAssist sInstance; + private String mLastQAndASpeakText; + + private boolean mHasFlush = false; + private boolean mInitReady = false; public static AIAssist getInstance( Context context ) { if ( sInstance == null ) { @@ -29,39 +48,125 @@ public class AIAssist implements VoiceClient.VoiceCmdCallBack { } public synchronized void release() { + Logger.d( TAG, "release" ); + if ( mCmdMap != null && !mCmdMap.isEmpty() && mVoiceClient != null ) { + for ( String cmd : mCmdMap.keySet() ) { + mVoiceClient.unRegisterCustomWakeupCmd( cmd ); + } + } + mQAndAMap.clear(); + mVoiceClient.release(); + mSpeakVoiceMap.clear(); + mCacheUnWakeupCommands.clear(); sInstance = null; } private final VoiceClient mVoiceClient; - private Map< String, IMogoVoiceCmdCallBack > mUnWakeupCmdMap = new HashMap<>(); + private MogoVoiceManager mogoVoiceManager; + // 免唤醒指令 + private Map< String, List< IMogoVoiceCmdCallBack > > mCmdMap = new HashMap<>(); + // 问答指令 + private Map< String, IMogoVoiceCmdCallBack > mQAndAMap = new HashMap<>(); + // 单独的语音播放 + private Map< String, IMogoVoiceCmdCallBack > mSpeakVoiceMap = new HashMap<>(); + + private Map< String, String[] > mCacheUnWakeupCommands = new ConcurrentHashMap<>(); private AIAssist( Context context ) { // private constructor mVoiceClient = new VoiceClient( context.getApplicationContext() ); mVoiceClient.setCallBack( this ); + initFlushStatus( context ); + initSpeech( context ); + Logger.w( TAG, "voice is ready = %s", mHasFlush ); + } + + private void initFlushStatus( Context context ) { + if ( !mHasFlush ) { + mHasFlush = isVoiceServiceReady( context ); + } + } + + /** + * 初始化 + */ + private void initSpeech( Context context ) { + mogoVoiceManager = MogoVoiceManagerImpl.getInstance(); + mogoVoiceManager.init( context, new OnConnStatusListener() { + @Override + public void onSuccess() { + mInitReady = true; + } + + @Override + public void onFailed() { + + } + } ); + } + + /** + * 是否语音注册成功 + * + * @return + */ + public boolean hasFlush() { + return mHasFlush; } @Override public void onCmdSelected( String cmd ) { - final IMogoVoiceCmdCallBack cmdCallBack = mUnWakeupCmdMap.get( cmd ); - if ( cmdCallBack != null ) { - cmdCallBack.onCmdSelected( cmd ); + if ( !mCmdMap.containsKey( cmd ) ) { + return; + } + Logger.d( TAG, "received command: %s", cmd ); + + Iterator< IMogoVoiceCmdCallBack > iterator = null; + try { + List< IMogoVoiceCmdCallBack > cmdCallBacks = mCmdMap.get( cmd ); + iterator = new ArrayList<>( cmdCallBacks ).iterator(); + } catch ( Exception e ) { + + } + while ( iterator != null && iterator.hasNext() ) { + IMogoVoiceCmdCallBack callBack = iterator.next(); + if ( callBack != null ) { + callBack.onCmdSelected( cmd ); + } } } @Override public void onCmdAction( String speakText ) { - + if ( !TextUtils.isEmpty( mLastQAndASpeakText ) ) { + IMogoVoiceCmdCallBack cmdCallBack = mQAndAMap.remove( mLastQAndASpeakText ); + if ( cmdCallBack != null ) { + cmdCallBack.onCmdAction( speakText ); + } + } } @Override public void onCmdCancel( String speakText ) { - + if ( !TextUtils.isEmpty( mLastQAndASpeakText ) ) { + IMogoVoiceCmdCallBack cmdCallBack = mQAndAMap.remove( mLastQAndASpeakText ); + if ( cmdCallBack != null ) { + cmdCallBack.onCmdCancel( speakText ); + } + } } @Override public void onSpeakEnd( String speakText ) { - IMogoVoiceCmdCallBack callBack = mUnWakeupCmdMap.get( speakText ); + if ( mQAndAMap.containsKey( speakText ) ) { + mLastQAndASpeakText = speakText; + IMogoVoiceCmdCallBack cmdCallBack = mQAndAMap.get( speakText ); + if ( cmdCallBack != null ) { + cmdCallBack.onSpeakEnd( speakText ); + return; + } + } + IMogoVoiceCmdCallBack callBack = mSpeakVoiceMap.remove( speakText ); if ( callBack != null ) { callBack.onSpeakEnd( speakText ); } @@ -69,34 +174,341 @@ public class AIAssist implements VoiceClient.VoiceCmdCallBack { @Override public void onSpeakSelectTimeOut( String speakText ) { - IMogoVoiceCmdCallBack callBack = mUnWakeupCmdMap.get( speakText ); + if ( mQAndAMap.containsKey( speakText ) ) { + if ( TextUtils.equals( speakText, mLastQAndASpeakText ) ) { + mLastQAndASpeakText = null; + } + IMogoVoiceCmdCallBack cmdCallBack = mQAndAMap.remove( speakText ); + if ( cmdCallBack != null ) { + cmdCallBack.onSpeakSelectTimeOut( speakText ); + return; + } + } + IMogoVoiceCmdCallBack callBack = mSpeakVoiceMap.remove( speakText ); if ( callBack != null ) { callBack.onSpeakSelectTimeOut( speakText ); } } - public void speakTTSVoice( String text ) { + /** + * 语音播报 + * + * @param text + */ + public void speakTTSVoice( String text, IMogoVoiceCmdCallBack callBack ) { try { - mVoiceClient.speakDefault( text ); + initFlushStatus( AbsMogoApplication.getApp() ); + if ( mHasFlush ) { + mSpeakVoiceMap.put( text, callBack ); + mVoiceClient.speakDefault( text ); + } } catch ( Exception e ) { } } + /** + * 语音播报 + * + * @param text + */ + public void speakTTSVoice( String text ) { + try { + initFlushStatus( AbsMogoApplication.getApp() ); + if ( mHasFlush ) { + mVoiceClient.speakDefault( text ); + } + } catch ( Exception e ) { + } + } + + /** + * 语音播报 + * + * @param text 播报内容 + * @param type 播报策略 + */ + public void speakTTSVoice( String text, VoicePreemptType type, IMogoVoiceCmdCallBack callBack ) { + try { + initFlushStatus( AbsMogoApplication.getApp() ); + if ( mHasFlush ) { + mSpeakVoiceMap.put( text, callBack ); + mVoiceClient.speakTypeText( text, type.getPreemptType() ); + } + } catch ( Exception e ) { + } + } + + /** + * 问答类型语音注册:默认确认和取消 + * + * @param tts 播报内容 + */ + public void speakQAndACmd( String tts, IMogoVoiceCmdCallBack callBack ) { + initFlushStatus( AbsMogoApplication.getApp() ); + if ( mHasFlush ) { + mQAndAMap.put( tts, callBack ); + mVoiceClient.speakTtsAndRegistCmd( tts ); + } + } + + /** + * 问答类型语音注册 + * + * @param tts 播报内容 + * @param okCmds 确认命令唤醒词 + * @param cancelCmds 取消命令唤醒词 + */ + public void speakQAndACmd( String tts, String[] okCmds, String[] cancelCmds, IMogoVoiceCmdCallBack callBack ) { + initFlushStatus( AbsMogoApplication.getApp() ); + if ( mHasFlush ) { + mQAndAMap.put( tts, callBack ); + mVoiceClient.speakTtsAndRegistCmd( tts, okCmds, cancelCmds ); + } + } + + /** + * 注册免唤醒命令 + * + * @param cmd + * @param cmdWords + * @param callBack + */ public void registerUnWakeupCommand( String cmd, String[] cmdWords, IMogoVoiceCmdCallBack callBack ) { - mUnWakeupCmdMap.put( cmd, callBack ); - mVoiceClient.registerCustomWakeupCmd( cmd, cmdWords ); + if ( !mCmdMap.containsKey( cmd ) ) { + mCmdMap.put( cmd, new ArrayList<>() ); + } + mCmdMap.get( cmd ).add( callBack ); + + initFlushStatus( AbsMogoApplication.getApp() ); + if ( mHasFlush ) { + mVoiceClient.registerCustomWakeupCmd( cmd, cmdWords ); + mCacheUnWakeupCommands.remove( cmd ); + } + Logger.i( TAG, "cache un wakeup command2. %s", cmd ); + mCacheUnWakeupCommands.put( cmd, cmdWords ); } - public void unregisterUnWakeupCommand( String cmd ) { - mUnWakeupCmdMap.remove( cmd ); + /** + * 注册免唤醒命令 + * + * @param cmd + * @param cmdWords + */ + public void registerUnWakeupCommand( String cmd, String[] cmdWords ) { + initFlushStatus( AbsMogoApplication.getApp() ); + if ( mHasFlush ) { + mVoiceClient.registerCustomWakeupCmd( cmd, cmdWords ); + mCacheUnWakeupCommands.remove( cmd ); + } + Logger.i( TAG, "cache un wakeup command. %s", cmd ); + mCacheUnWakeupCommands.put( cmd, cmdWords ); + } + + /** + * 注册免唤醒命令回调 + * + * @param cmd + * @param callBack + */ + public synchronized void registerUnWakeupCommandCallback( String cmd, IMogoVoiceCmdCallBack callBack ) { + if ( !mCmdMap.containsKey( cmd ) ) { + mCmdMap.put( cmd, new ArrayList<>() ); + } + mCmdMap.get( cmd ).add( callBack ); + } + + /** + * 注销免唤醒命令 + * + * @param cmd + */ + public synchronized void unregisterUnWakeupCommand( String cmd ) { + mCmdMap.remove( cmd ); mVoiceClient.unRegisterCustomWakeupCmd( cmd ); + mCacheUnWakeupCommands.remove( cmd ); } - public void registerTTSCallback( String tts, IMogoVoiceCmdCallBack cmdCallBack ) { - mUnWakeupCmdMap.put( tts, cmdCallBack ); + /** + * 注销免唤醒命令 + * + * @param cmd + */ + public synchronized void unregisterUnWakeupCommand( String cmd, IMogoVoiceCmdCallBack callBack ) { + if ( mCmdMap.containsKey( cmd ) ) { + List< IMogoVoiceCmdCallBack > callBacks = mCmdMap.get( cmd ); + if ( callBacks != null ) { + callBacks.remove( callBack ); + } + if ( callBacks.isEmpty() ) { + mCmdMap.remove( cmd ); + mVoiceClient.unRegisterCustomWakeupCmd( cmd ); + mCacheUnWakeupCommands.remove( cmd ); + } + } } - public void unregisterTTSCallback( String tts ) { - mUnWakeupCmdMap.remove( tts ); + public static void startAssistant( Context context ) { + startAssistant( context, 1 ); } + + /** + * @param context + * @param status window_start_cancel 0 - 结束, 1 - 显示, 2 - 未激活调试进入 + */ + public static void startAssistant( Context context, int status ) { + final Intent intent = new Intent(); + intent.setFlags( Intent.FLAG_INCLUDE_STOPPED_PACKAGES ); + intent.setAction( "pvetec.intent.action.txz.switch" ); + intent.putExtra( "window_start_cancel", status ); + intent.putExtra( "extra_switch_type", "window_start_cancel" ); + Logger.d( TAG, "status = %d", status ); + context.sendBroadcast( intent ); + } + + public synchronized void flush() { + if ( mCacheUnWakeupCommands.isEmpty() ) { + return; + } + mHasFlush = true; + Logger.d( TAG, "flush cache voice command when voice service ready." ); + final Map< String, String[] > tmp = new HashMap<>( mCacheUnWakeupCommands ); + for ( String cmd : tmp.keySet() ) { + registerUnWakeupCommand( cmd, tmp.get( cmd ) ); + } + } + + private boolean isVoiceServiceReady( Context context ) { + if ( isProcessRunning( context, getPackageUid( context, "com.zhidao.speech" ) ) + && isProcessRunning( context, getPackageUid( context, "com.zhidao.speech.adapter" ) ) ) { + return true; + } else if (isProcessRunning(context, getPackageUid(context, "com.txznet.txz")) && isProcessRunning(context, getPackageUid(context, "com.txznet.adapter"))) { + Logger.d(TAG, "txz is voiceServiceReady"); + return true; + } + return false; + } + +// private boolean isRunningTaskExist( Context context, String processName ) { +//// ActivityManager am = ( ActivityManager ) context.getSystemService( Context.ACTIVITY_SERVICE ); +//// List< ActivityManager.RunningAppProcessInfo > processList = am.getRunningAppProcesses(); +//// for ( ActivityManager.RunningAppProcessInfo info : processList ) { +//// if ( info.processName.equals( processName ) ) { +//// return true; +//// } +//// } +//// return false; +//// } + + /** + * 方法描述:判断某一应用是否正在运行 + * Created by cafeting on 2017/2/4. + * + * @param context 上下文 + * @param packageName 应用的包名 + * @return true 表示正在运行,false 表示没有运行 + */ + public static boolean isAppRunning( Context context, String packageName ) { + ActivityManager am = ( ActivityManager ) context.getSystemService( Context.ACTIVITY_SERVICE ); + List< ActivityManager.RunningTaskInfo > list = am.getRunningTasks( 100 ); + if ( list.size() <= 0 ) { + return false; + } + for ( ActivityManager.RunningTaskInfo info : list ) { + if ( info.baseActivity.getPackageName().equals( packageName ) ) { + return true; + } + } + return false; + } + + + //获取已安装应用的 uid,-1 表示未安装此应用或程序异常 + public static int getPackageUid( Context context, String packageName ) { + try { + ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo( packageName, 0 ); + if ( applicationInfo != null ) { + return applicationInfo.uid; + } + } catch ( Exception e ) { + return -1; + } + return -1; + } + + /** + * 判断某一 uid 的程序是否有正在运行的进程,即是否存活 + * Created by cafeting on 2017/2/4. + * + * @param context 上下文 + * @param uid 已安装应用的 uid + * @return true 表示正在运行,false 表示没有运行 + */ + public static boolean isProcessRunning( Context context, int uid ) { + ActivityManager am = ( ActivityManager ) context.getSystemService( Context.ACTIVITY_SERVICE ); + List< ActivityManager.RunningServiceInfo > runningServiceInfos = am.getRunningServices( 200 ); + if ( runningServiceInfos.size() > 0 ) { + for ( ActivityManager.RunningServiceInfo appProcess : runningServiceInfos ) { + if ( uid == appProcess.uid ) { + return true; + } + } + } + return false; + } + + public void speakTTSAndDuck( String text ) { + speakTTSAndDuck( text, null ); + } + + public void speakTTSAndDuck( String text, IMogoVoiceCmdCallBack callBack ) { + try { + if ( mInitReady ) { + mSpeakVoiceMap.put( text, callBack ); + mogoVoiceManager.toSpeak( text, -3, this ); + } + } catch ( Exception e ) { + } + } + + public void shutUp( String ttsId, String text ) { + try { + mSpeakVoiceMap.remove( text ); + mogoVoiceManager.shutUp( ttsId ); + } catch ( Exception e ) { + + } + } + + public void clearTTSCallback( String text ) { + try { + mSpeakVoiceMap.remove( text ); + } catch ( Exception e ) { + e.printStackTrace(); + } + } + + @Override + public void onTtsStart( String ttsId, String text ) { + IMogoVoiceCmdCallBack callBack = mSpeakVoiceMap.get( text ); + if ( callBack != null ) { + callBack.onTTSStart( ttsId, text ); + } + } + + @Override + public void onTtsFinish( String ttsId, String text ) { + IMogoVoiceCmdCallBack callBack = mSpeakVoiceMap.remove( text ); + if ( callBack != null ) { + callBack.onTTSEnd( ttsId, text ); + } + } + + @Override + public void onTtsError( String ttsId, String text ) { + IMogoVoiceCmdCallBack callBack = mSpeakVoiceMap.remove( text ); + if ( callBack != null ) { + callBack.onTTSError( ttsId, text ); + } + } + } diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/IMogoVoiceCmdCallBack.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/IMogoVoiceCmdCallBack.java index b213d117fa..eb26dc64f6 100644 --- a/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/IMogoVoiceCmdCallBack.java +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/IMogoVoiceCmdCallBack.java @@ -1,38 +1,66 @@ package com.mogo.commons.voice; public interface IMogoVoiceCmdCallBack { + + /** + * 新SDK接口 + * + * @param ttsId + * @param tts + */ + default void onTTSStart( String ttsId, String tts ) { + } + + /** + * 新SDK接口 + * + * @param ttsId + * @param tts + */ + default void onTTSEnd( String ttsId, String tts ) { + } + + /** + * 新SDK接口 + * + * @param ttsId + * @param tts + */ + default void onTTSError( String ttsId, String tts ) { + } + /** * 免唤醒命令响应回调 * * @param cmd */ - void onCmdSelected( String cmd ); + default void onCmdSelected( String cmd ){} /** * 语音播报临时免唤醒“确定”命令 * * @param speakText 播报内容 */ - void onCmdAction( String speakText ); + default void onCmdAction( String speakText ){} /** * 语音播报临时免唤醒“取消”命令 * * @param speakText 播报内容 */ - void onCmdCancel( String speakText ); + default void onCmdCancel( String speakText ){} /** * 语音播报完毕 * * @param speakText 播报内容 */ - void onSpeakEnd( String speakText ); + default void onSpeakEnd( String speakText ){} /** * 语音播报完临时命令选择超时 * * @param speakText 播报内容 */ - void onSpeakSelectTimeOut( String speakText ); + default void onSpeakSelectTimeOut( String speakText ){} } \ No newline at end of file diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/VoiceIntentTrack.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/VoiceIntentTrack.java new file mode 100644 index 0000000000..8c1a6c9b75 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/VoiceIntentTrack.java @@ -0,0 +1,16 @@ +package com.mogo.commons.voice; + + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Target({TYPE, METHOD, CONSTRUCTOR}) +@Retention(RUNTIME) +public @interface VoiceIntentTrack { + +} \ No newline at end of file diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/VoicePreemptType.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/VoicePreemptType.java new file mode 100644 index 0000000000..aef7e63252 --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/VoicePreemptType.java @@ -0,0 +1,23 @@ +package com.mogo.commons.voice; + +import com.zhidao.auto.platform.voice.VoiceClient; + +public enum VoicePreemptType { + + + PREEMPT_TYPE_NONE( VoiceClient.PreemptType.PREEMPT_TYPE_NONE ), //不打断 + PREEMPT_TYPE_IMMEADIATELY( VoiceClient.PreemptType.PREEMPT_TYPE_IMMEADIATELY ), //立即打断,取消当前的tts插队播放 + PREEMPT_TYPE_NEXT( VoiceClient.PreemptType.PREEMPT_TYPE_NEXT ), //下一个插入,不取消当前的tts,插队下一个播放 + PREEMPT_TYPE_FLUSH( VoiceClient.PreemptType.PREEMPT_TYPE_FLUSH ), //清空队列 + PREEMPT_TYPE_IMMEADIATELY_WITHOUT_CANCLE( VoiceClient.PreemptType.PREEMPT_TYPE_IMMEADIATELY_WITHOUT_CANCLE ); //立即打断,不取消当前tts + + public VoiceClient.PreemptType preemptType; + + VoicePreemptType( VoiceClient.PreemptType preemptType ) { + this.preemptType = preemptType; + } + + public VoiceClient.PreemptType getPreemptType() { + return preemptType; + } +} \ No newline at end of file diff --git a/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/VoiceTrack.java b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/VoiceTrack.java new file mode 100644 index 0000000000..d1ef2c606f --- /dev/null +++ b/foudations/mogo-commons/src/main/java/com/mogo/commons/voice/VoiceTrack.java @@ -0,0 +1,16 @@ +package com.mogo.commons.voice; + + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Target({TYPE, METHOD, CONSTRUCTOR}) +@Retention(RUNTIME) +public @interface VoiceTrack { + +} \ No newline at end of file diff --git a/foudations/mogo-commons/src/main/res/drawable/module_commons_toast_bkg.xml b/foudations/mogo-commons/src/main/res/drawable/module_commons_toast_bkg.xml new file mode 100644 index 0000000000..58389abf7c --- /dev/null +++ b/foudations/mogo-commons/src/main/res/drawable/module_commons_toast_bkg.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/foudations/mogo-commons/src/main/res/layout/module_commons_layout_toast.xml b/foudations/mogo-commons/src/main/res/layout/module_commons_layout_toast.xml new file mode 100644 index 0000000000..0b01115f63 --- /dev/null +++ b/foudations/mogo-commons/src/main/res/layout/module_commons_layout_toast.xml @@ -0,0 +1,27 @@ + + + + + \ No newline at end of file diff --git a/foudations/mogo-commons/src/main/res/values-xhdpi/dimens.xml b/foudations/mogo-commons/src/main/res/values-xhdpi/dimens.xml new file mode 100644 index 0000000000..c1558d9ba0 --- /dev/null +++ b/foudations/mogo-commons/src/main/res/values-xhdpi/dimens.xml @@ -0,0 +1,13 @@ + + + 50px + 50px + 32px + 32px + 40px + 698px + 900px + 130px + + + diff --git a/foudations/mogo-commons/src/main/res/values/dimens.xml b/foudations/mogo-commons/src/main/res/values/dimens.xml new file mode 100644 index 0000000000..54534fb37b --- /dev/null +++ b/foudations/mogo-commons/src/main/res/values/dimens.xml @@ -0,0 +1,11 @@ + + + 30px + 30px + 16px + 16px + 22px + 371px + 500px + 72px + \ No newline at end of file diff --git a/foudations/mogo-utils/build.gradle b/foudations/mogo-utils/build.gradle index 11eb8bcdca..08408aa350 100644 --- a/foudations/mogo-utils/build.gradle +++ b/foudations/mogo-utils/build.gradle @@ -1,15 +1,14 @@ apply plugin: 'com.android.library' - +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' android { - compileSdkVersion 29 - buildToolsVersion "29.0.2" - - + compileSdkVersion rootProject.ext.android.compileSdkVersion + // buildToolsVersion rootProject.ext.android.buildToolsVersion defaultConfig { - minSdkVersion 19 - targetSdkVersion 29 - versionCode 1 - versionName "1.0" + minSdkVersion rootProject.ext.android.minSdkVersion + targetSdkVersion rootProject.ext.android.targetSdkVersion + versionCode Integer.valueOf(VERSION_CODE) + versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION") testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' @@ -22,11 +21,17 @@ android { } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) api rootProject.ext.dependencies.glide + implementation rootProject.ext.dependencies.kotlinstdlibjdk7 implementation rootProject.ext.dependencies.glideanno implementation rootProject.ext.dependencies.glideokhttp3 implementation rootProject.ext.dependencies.supportannos @@ -37,4 +42,11 @@ dependencies { api rootProject.ext.dependencies.retrofitconvertergson api rootProject.ext.dependencies.retrofitconverterscalars implementation rootProject.ext.dependencies.androidxappcompat + if (Boolean.valueOf(RELEASE)) { + + } else { + + } } + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() diff --git a/foudations/mogo-utils/consumer-rules.pro b/foudations/mogo-utils/consumer-rules.pro index e69de29bb2..8deab7089d 100644 --- a/foudations/mogo-utils/consumer-rules.pro +++ b/foudations/mogo-utils/consumer-rules.pro @@ -0,0 +1,5 @@ +#-----MogoUtils----- +-keep class com.mogo.utils.network.CallerType +-keep class com.mogo.utils.network.CallerRestrictTo +-keep class com.mogo.utils.glide.GlideRoundedCornersTransform.CornerType +-keep class com.mogo.utils.logger.LogLevel \ No newline at end of file diff --git a/foudations/mogo-utils/gradle.properties b/foudations/mogo-utils/gradle.properties new file mode 100644 index 0000000000..914f308c6e --- /dev/null +++ b/foudations/mogo-utils/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.commons +POM_ARTIFACT_ID=mogo-utils +VERSION_CODE=1 diff --git a/foudations/mogo-utils/proguard-rules.pro b/foudations/mogo-utils/proguard-rules.pro index f1b424510d..664ac30532 100644 --- a/foudations/mogo-utils/proguard-rules.pro +++ b/foudations/mogo-utils/proguard-rules.pro @@ -19,3 +19,9 @@ # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile + +#-----MogoUtils----- +-keep class com.mogo.utils.network.CallerType +-keep class com.mogo.utils.network.CallerRestrictTo +-keep class com.mogo.utils.glide.GlideRoundedCornersTransform.CornerType +-keep class com.mogo.utils.logger.LogLevel \ No newline at end of file diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/AppUtils.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/AppUtils.java new file mode 100644 index 0000000000..d5900526a1 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/AppUtils.java @@ -0,0 +1,60 @@ +package com.mogo.utils; + +import android.app.ActivityManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.text.TextUtils; + +import java.util.List; + +/** + * @author congtaowang + * @since 2020-04-09 + *

+ * 描述 + */ +public class AppUtils { + + public static boolean isApplicationBroughtToBackground( final Context context ) { + ActivityManager am = ( ActivityManager ) context.getSystemService( Context.ACTIVITY_SERVICE ); + List< ActivityManager.RunningTaskInfo > tasks = am.getRunningTasks( 1 ); + if ( !tasks.isEmpty() ) { + ComponentName topActivity = tasks.get( 0 ).topActivity; + if ( !topActivity.getPackageName().equals( context.getPackageName() ) ) { + return true; + } + } + return false; + } + + public static boolean isAppInstalled( Context context, String pkg ) { + PackageInfo packageInfo; + if ( TextUtils.isEmpty( pkg ) ) { + return false; + } + try { + packageInfo = context.getPackageManager().getPackageInfo( pkg, 0 ); + } catch ( PackageManager.NameNotFoundException e ) { + packageInfo = null; + e.printStackTrace(); + } + if ( packageInfo == null ) { + return false; + } else { + return true; + } + } + + public static String getApplicationLabel( Context context, String pkgName ) { + try { + PackageManager pm = context.getPackageManager(); + ApplicationInfo appInfo = pm.getApplicationInfo( pkgName, PackageManager.GET_META_DATA ); + return pm.getApplicationLabel( appInfo ).toString(); + } catch ( Exception e ) { + return null; + } + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/AssetsUtils.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/AssetsUtils.java new file mode 100644 index 0000000000..7ec9448cd7 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/AssetsUtils.java @@ -0,0 +1,37 @@ +package com.mogo.utils; + +import android.content.Context; +import android.text.TextUtils; +import android.util.Log; +import java.io.BufferedInputStream; +import java.io.InputStream; + +/** + * @author congtaowang + * @since 2019-12-12 + *

+ * 读取asset文件 + */ +public class AssetsUtils { + + private static final String TAG = "amap.AssetsUtils"; + + public static byte[] read( Context context, String fileName ) { + if ( context == null || TextUtils.isEmpty( fileName ) ) { + return null; + } + byte[] buffer = null; + try { + InputStream is = context.getAssets().open( fileName ); + BufferedInputStream bis = new BufferedInputStream( is ); + buffer = new byte[is.available()]; + bis.read( buffer ); + bis.close(); + is.close(); + Log.d( TAG, "read assets success: " + fileName + " size=" + buffer.length ); + } catch ( Exception e ) { + e.printStackTrace(); + } + return buffer; + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/LaunchUtils.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/LaunchUtils.java new file mode 100644 index 0000000000..6746d193e3 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/LaunchUtils.java @@ -0,0 +1,29 @@ +package com.mogo.utils; + +import android.content.Context; +import android.content.Intent; + +/** + * @author congtaowang + * @since 2020-02-03 + *

+ * 描述 + */ +public class LaunchUtils { + + /** + * 通过包名启动app + * + * @param context + * @param pkg 包名 + */ + public static void launchByPkg( Context context, String pkg ) throws Exception { + Intent intent = getLaunchIntentForPackage( context, pkg ); + intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK ); + context.startActivity( intent ); + } + + public static Intent getLaunchIntentForPackage( Context context, String pkg ) { + return context.getPackageManager().getLaunchIntentForPackage( pkg ); + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/NetworkUtils.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/NetworkUtils.java new file mode 100644 index 0000000000..4481f10508 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/NetworkUtils.java @@ -0,0 +1,110 @@ +package com.mogo.utils; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import androidx.annotation.Nullable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class NetworkUtils { + private static final String TAG = NetworkUtils.class.getSimpleName(); + + /** + * Returns true if device is connected to wifi or mobile network, false + * otherwise. + * + * @param context + * @return + */ + public static boolean isConnected( Context context ) { + + if ( context == null ) { + return false; + } + + ConnectivityManager conMan = (ConnectivityManager) context + .getSystemService( Context.CONNECTIVITY_SERVICE ); + + if ( conMan == null ) { + return false; + } + + NetworkInfo infoWifi = conMan.getNetworkInfo( ConnectivityManager.TYPE_WIFI ); + if ( infoWifi != null ) { + NetworkInfo.State wifi = infoWifi.getState(); + if ( wifi == NetworkInfo.State.CONNECTED ) { + return true; + } + } + + NetworkInfo infoMobile = conMan.getNetworkInfo( ConnectivityManager.TYPE_MOBILE ); + if ( infoMobile != null ) { + NetworkInfo.State mobile = infoMobile.getState(); + if ( mobile == NetworkInfo.State.CONNECTED ) { + return true; + } + } + return false; + } + + /** + * Check if there is any connectivity to a Wifi network + * + * @param context + * @return + */ + public static boolean isConnectedWifi( Context context ) { + if ( context == null ) { + return false; + } + NetworkInfo info = getNetworkInfo( context ); + return ( info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI ); + } + + /** + * Check if there is any connectivity to a mobile network + * + * @param context + * @return + */ + public static boolean isConnectedMobile( Context context ) { + if ( context == null ) { + return false; + } + NetworkInfo info = getNetworkInfo( context ); + return ( info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE ); + } + + /** + * Get the network info + * + * @param context + * @return + */ + @Nullable + public static NetworkInfo getNetworkInfo( Context context ) { + if ( context == null ) { + return null; + } + ConnectivityManager cm = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE ); + if ( cm != null ) { + return cm.getActiveNetworkInfo(); + } + return null; + } + + /** + * URL + * + * @param url + * @return true ,false + */ + public static boolean isNetworkUrl( String url ) { + String regex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"; + Pattern patt = Pattern.compile( regex ); + Matcher matcher = patt.matcher( url ); + return matcher.matches(); + } + +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/OnItemClickedListener.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/OnItemClickedListener.java new file mode 100644 index 0000000000..fa7065448e --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/OnItemClickedListener.java @@ -0,0 +1,12 @@ +package com.mogo.utils; + +/** + * @author congtaowang + * @since 2019-10-02 + *

+ * recyclerview item 点击回调 + */ +public interface OnItemClickedListener< T > { + + void onItemClicked(T obj); +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/ResourcesHelper.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/ResourcesHelper.java index c46161df83..8afecd5fb2 100644 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/ResourcesHelper.java +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/ResourcesHelper.java @@ -10,63 +10,72 @@ import android.util.DisplayMetrics; public class ResourcesHelper { - public static Resources getResources( Context context){ + public static Resources getResources( Context context ) { return context.getResources(); } - public static int getColor( Context context, int rid) { - return getResources(context).getColor(rid); + public static int getColor( Context context, int rid ) { + return getResources( context ).getColor( rid ); } - public static ColorStateList getColorStateList( Context context, int rid) { - return getResources(context).getColorStateList(rid); + public static ColorStateList getColorStateList( Context context, int rid ) { + return getResources( context ).getColorStateList( rid ); } - public static String getString( Context context, int rid) { - return getResources(context).getString(rid); + public static String getString( Context context, int rid ) { + return getResources( context ).getString( rid ); } - public static String getString( Context context, int rid, int param1, int param2) { - return getResources(context).getString(rid, param1, param2); + public static String getString( Context context, int rid, int param1, int param2 ) { + return getResources( context ).getString( rid, param1, param2 ); } - public static String getString( Context context, int rid, String str) { - return getResources(context).getString(rid, str); + public static String getString( Context context, int rid, String str ) { + return getResources( context ).getString( rid, str ); } - public static String[] getStringArray( Context context, int rid) { - return getResources(context).getStringArray(rid); + public static String[] getStringArray( Context context, int rid ) { + return getResources( context ).getStringArray( rid ); } - public static Drawable getDrawable( Context context, int rid) { - return getResources(context).getDrawable(rid); + public static Drawable getDrawable( Context context, int rid ) { + return getResources( context ).getDrawable( rid ); } - public static float getDimension( Context context, int rid) { - return getResources(context).getDimension(rid); + public static float getDimension( Context context, int rid ) { + return getResources( context ).getDimension( rid ); } - public static DisplayMetrics getDisplayMetrics( Context context) { - return getResources(context).getDisplayMetrics(); + public static DisplayMetrics getDisplayMetrics( Context context ) { + return getResources( context ).getDisplayMetrics(); } - public static int getDisplayMetrics( Context context, int x) { - return getResources(context).getDimensionPixelSize(x); + public static int getDisplayMetrics( Context context, int x ) { + return getResources( context ).getDimensionPixelSize( x ); } - public static int getDimensionPixelSize( Context context, int x) { - return getResources(context).getDimensionPixelSize(x); + public static int getDimensionPixelSize( Context context, int x ) { + return getResources( context ).getDimensionPixelSize( x ); } - public static int getInteger( Context context, int rid) { - return getResources(context).getInteger(rid); + public static int getInteger( Context context, int rid ) { + return getResources( context ).getInteger( rid ); } - public static XmlResourceParser getXml( Context context, int rid) { - return getResources(context).getXml(rid); + public static XmlResourceParser getXml( Context context, int rid ) { + return getResources( context ).getXml( rid ); } - public static Configuration getConfiguration( Context context) { - return getResources(context).getConfiguration(); + public static Configuration getConfiguration( Context context ) { + return getResources( context ).getConfiguration(); + } + + public static String getResNameById( Context context, int id ) { + try { + return context.getResources().getResourceName( id ); + } catch ( Exception e ) { + e.printStackTrace(); + return String.valueOf( id ); + } } } diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/SoftKeyBoardJobber.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/SoftKeyBoardJobber.java new file mode 100644 index 0000000000..ee88b09c3d --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/SoftKeyBoardJobber.java @@ -0,0 +1,121 @@ +package com.mogo.utils; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Rect; +import android.os.Build; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; + +public class SoftKeyBoardJobber { + + public static boolean hideIfNecessary( Activity context, MotionEvent ev ) { + if ( ev.getAction() == MotionEvent.ACTION_DOWN ) { + View v = context.getCurrentFocus(); + if ( isShouldHideInput( v, ev ) ) { + InputMethodManager imm = ( InputMethodManager ) context.getSystemService( Context.INPUT_METHOD_SERVICE ); + if ( imm != null ) { + imm.hideSoftInputFromWindow( v.getWindowToken(), 0 ); + return true; + } + } + } + return false; + } + + private static boolean isShouldHideInput( View v, MotionEvent event ) { + if ( v != null && ( v instanceof EditText ) ) { + int[] leftTop = {0, 0}; + // 获取输入框当前的location位置 + v.getLocationInWindow( leftTop ); + int left = leftTop[0]; + int top = leftTop[1]; + int bottom = top + v.getHeight(); + int right = left + v.getWidth(); + return !( event.getX() > left && event.getX() < right && event.getY() > top && event.getY() < bottom ); + } + return false; + } + + public static void hide( Context context, View v ) { + InputMethodManager imm = getInputMethodManager( context ); + if ( imm != null ) { + imm.hideSoftInputFromWindow( v.getWindowToken(), 0 ); + } + } + + public static void show( Context context ) { + InputMethodManager imm = getInputMethodManager( context ); + if ( imm != null ) { + imm.toggleSoftInput( 0, InputMethodManager.HIDE_NOT_ALWAYS ); + } + } + + private static InputMethodManager imm = null; + + private static InputMethodManager getInputMethodManager( Context context ) { + if ( imm == null ) { + imm = ( InputMethodManager ) context.getSystemService( Context.INPUT_METHOD_SERVICE ); + } + return imm; + } + + public interface OnSoftKeyboardChangeListener { + void onSoftKeyBoardChange( int softKeyboardHeight, boolean visible ); + } + + public static ViewTreeObserver.OnGlobalLayoutListener observeSoftKeyboard( Activity activity, final OnSoftKeyboardChangeListener listener ) { + if ( !isAliveActivity( activity ) || listener == null ) { + return null; + } + final View decorView = activity.getWindow().getDecorView(); + ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() { + + int previousKeyboardHeight = -1; + Rect rect = new Rect(); + boolean lastVisibleState = false; + + @Override + public void onGlobalLayout() { + rect.setEmpty(); + decorView.getWindowVisibleDisplayFrame( rect ); + int displayHeight = rect.bottom - rect.top; + int height = decorView.getHeight() - rect.top; + int keyboardHeight = height - displayHeight; + if ( previousKeyboardHeight != keyboardHeight ) { + boolean hide = ( double ) displayHeight / height > 0.8; + if ( hide != lastVisibleState ) { + listener.onSoftKeyBoardChange( keyboardHeight, !hide ); + lastVisibleState = hide; + } + } + previousKeyboardHeight = height; + } + }; + decorView.getViewTreeObserver().addOnGlobalLayoutListener( onGlobalLayoutListener ); + return onGlobalLayoutListener; + } + + public static void removeSoftKeyboardObserver( Activity activity, ViewTreeObserver.OnGlobalLayoutListener listener ) { + if ( !isAliveActivity( activity ) || listener == null ) { + return; + } + final View decorView = activity.getWindow().getDecorView(); + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN ) { + decorView.getViewTreeObserver().removeOnGlobalLayoutListener( listener ); + } else { + decorView.getViewTreeObserver().removeGlobalOnLayoutListener( listener ); + } + } + + private static boolean isAliveActivity( Activity activity ) { + return activity != null + && activity.getWindow() != null + && activity.getWindow().getDecorView() != null + && activity.getWindow().getDecorView().getViewTreeObserver() != null; + } + +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/SoftKeyboardUtils.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/SoftKeyboardUtils.java deleted file mode 100644 index ed4cf52ce4..0000000000 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/SoftKeyboardUtils.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.mogo.utils; - -import android.content.Context; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; - -/** - * Created by congtaowang on 2018/12/20. - */ -public class SoftKeyboardUtils { - - public static void show( Context context ) { - try { - InputMethodManager imm = ( InputMethodManager ) context.getSystemService( Context.INPUT_METHOD_SERVICE ); - if ( imm != null ) { - imm.toggleSoftInput( 0, InputMethodManager.HIDE_NOT_ALWAYS ); - } - } catch ( Exception e ) { - e.printStackTrace(); - } - } - - public static void hidden( Context context, EditText editText ) { - try { - InputMethodManager imm = ( InputMethodManager ) context.getSystemService( Context.INPUT_METHOD_SERVICE ); - if ( imm != null ) { - imm.hideSoftInputFromWindow( editText.getWindowToken(), 0 ); - } - } catch ( Exception e ) { - e.printStackTrace(); - } - } -} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/ThreadPoolService.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/ThreadPoolService.java index 3fb2341761..9fc2ac60eb 100644 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/ThreadPoolService.java +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/ThreadPoolService.java @@ -2,10 +2,33 @@ package com.mogo.utils; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; public class ThreadPoolService { - private static final ExecutorService SERVICE = Executors.newScheduledThreadPool( 1 ); + private static final ExecutorService SERVICE = Executors.newFixedThreadPool( 3, new ThreadFactoryImpl() ); + private static final ExecutorService SINGLE_THREAD_SERVICE = Executors.newSingleThreadExecutor(new SingleThreadFactoryImpl()); + private static class ThreadFactoryImpl implements ThreadFactory { + + private static int mCounter = 1; + + @Override + public Thread newThread( Runnable r ) { + return new Thread( r, "ThreadPoolService - " + mCounter++ ); + } + } + + /** + * 单线程队列执行的ThreadFactory实现,应该只会new一个Thread + */ + private static class SingleThreadFactoryImpl implements ThreadFactory{ + private static int counter = 1; + + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "SingleThread - " + counter++); + } + } private ThreadPoolService() { } @@ -13,4 +36,8 @@ public class ThreadPoolService { public static void execute( Runnable task ) { SERVICE.execute( task ); } + + public static void singleExecute(Runnable task) { + SINGLE_THREAD_SERVICE.execute(task); + } } \ No newline at end of file diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/TipToast.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/TipToast.java index 93af03bbae..ec457c6b04 100644 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/TipToast.java +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/TipToast.java @@ -9,6 +9,7 @@ package com.mogo.utils; import android.content.Context; import android.os.Handler; import android.text.TextUtils; +import android.view.Gravity; import android.view.View; import android.widget.Toast; @@ -144,10 +145,6 @@ public final class TipToast { sToast.cancel(); } - if ( sGenerator == null ) { - sToast = Toast.makeText( context, msg, duration ); - } - if ( sGenerator == null ) { sToast = Toast.makeText( context, msg, duration ); } else { @@ -155,6 +152,7 @@ public final class TipToast { final View view = sGenerator.make( context, msg ); if ( view != null ) { sToast.setView( view ); + sToast.setGravity( sGenerator.gravity(), sGenerator.xOffset(), sGenerator.yOffset() ); sToast.setDuration( duration ); } else { sToast = Toast.makeText( context, msg, duration ); @@ -171,6 +169,18 @@ public final class TipToast { public interface ToastViewGenerator { View make( Context context, String message ); + + default int gravity() { + return Gravity.CENTER; + } + + default int yOffset() { + return 0; + } + + default int xOffset() { + return 0; + } } } diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/WindowUtils.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/WindowUtils.java index 65416700e8..fa9d8eb49c 100644 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/WindowUtils.java +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/WindowUtils.java @@ -29,6 +29,9 @@ public class WindowUtils { return ( int ) ( dpValue * scale + 0.5f ); } + + + /** * 根据手机的分辨率从 px(像素) 的单位 转成为 dp */ diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/WorkThreadHandler.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/WorkThreadHandler.java new file mode 100644 index 0000000000..6411267066 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/WorkThreadHandler.java @@ -0,0 +1,72 @@ +package com.mogo.utils; + +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; + +/** + * @author congtaowang + * @since 2020-03-23 + *

+ * 描述 + */ +public class WorkThreadHandler { + + private Looper mThreadLooper; + private Handler mHandler; + private HandlerThread mThread; + + private WorkThreadHandler() { + // private constructor + mThread = new HandlerThread( "work-thread-handler" ); + mThread.start(); + mThreadLooper = mThread.getLooper(); + mHandler = new Handler( mThreadLooper ); + } + + private static final class InstanceHolder { + private static final WorkThreadHandler INSTANCE = new WorkThreadHandler(); + } + + public static WorkThreadHandler getInstance() { + return InstanceHolder.INSTANCE; + } + + public Looper getLooper() { + return mThreadLooper; + } + + private Object readResolve() { + // 阻止反序列化,必须实现 Serializable 接口 + return InstanceHolder.INSTANCE; + } + + private Object sToken = new Object(); + + public boolean post( Runnable r ) { + return mHandler != null && mHandler.post( r ); + } + + public boolean postDelayed( Runnable r, long delayMillis ) { + return mHandler != null && mHandler.postDelayed( r, delayMillis ); + } + + public Handler getWorkThreadHandler() { + return mHandler; + } + + public boolean postOnceDelayed( Runnable r, long delayMillis ) { + if ( mHandler == null ) { + return false; + } else { + mHandler.removeCallbacks( r, sToken ); + return mHandler.postDelayed( r, delayMillis ); + } + } + + public void removeCallbacks( Runnable runnable ) { + if ( mHandler != null ) { + mHandler.removeCallbacks( runnable ); + } + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/glide/BaseGlideModule.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/glide/BaseGlideModule.java index b77e27d37f..33f5bc5563 100644 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/glide/BaseGlideModule.java +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/glide/BaseGlideModule.java @@ -1,6 +1,7 @@ package com.mogo.utils.glide; import android.content.Context; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -12,6 +13,7 @@ import com.bumptech.glide.load.engine.Resource; import com.bumptech.glide.load.engine.cache.ExternalPreferredCacheDiskCacheFactory; import com.bumptech.glide.load.engine.cache.LruResourceCache; import com.bumptech.glide.load.engine.cache.MemoryCache; +import com.bumptech.glide.load.engine.executor.GlideExecutor; import com.bumptech.glide.module.AppGlideModule; /** @@ -32,7 +34,9 @@ public class BaseGlideModule extends AppGlideModule { * * 是在sdcard/Android/data/包名/cache/DISK_CACHE_NAME目录当中 */ + builder.setLogLevel(Log.VERBOSE); builder.setMemoryCache( new LruResourceCache( MEMORY_CACHE_SIZE ) ); builder.setDiskCache( new ExternalPreferredCacheDiskCacheFactory( context, DISK_CACHE_NAME, DISK_CACHE_SIZE ) ); + builder.setDiskCacheExecutor(GlideExecutor.newDiskCacheExecutor(GlideExecutor.UncaughtThrowableStrategy.DEFAULT)); } } diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/glide/GlideBlurTransformation.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/glide/GlideBlurTransformation.java new file mode 100644 index 0000000000..9ee136f036 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/glide/GlideBlurTransformation.java @@ -0,0 +1,67 @@ +package com.mogo.utils.glide; + +import android.content.Context; +import android.graphics.Bitmap; +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.RenderScript; +import android.renderscript.ScriptIntrinsicBlur; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; +import com.bumptech.glide.load.resource.bitmap.CenterCrop; +import com.mogo.utils.logger.Logger; + +/** + * 使用Glide加载图片时,使该图片进行高斯模糊 + * 基本用法:Glide.with(this).load(userInfo.headImgurl).apply(RequestOptions.bitmapTransform(GlideBlurTransformation(this))).into(ivCardBg) + * 如果想用多个Transform可以使用{@link com.bumptech.glide.load.MultiTransformation} 进行Transform的融合 + * @author tongchenfei + */ +public class GlideBlurTransformation extends CenterCrop { + private static final float DEFAULT_BLUR_RADIUS = 25F; + private static final float DEFAULT_OUT_WIDTH_SCALE = 0.5F; + + private Context context; + private float blurRadius; + private float outScale; + public GlideBlurTransformation(Context context) { + this(context, DEFAULT_BLUR_RADIUS); + } + + public GlideBlurTransformation(Context context, float blurRadius) { + this(context, blurRadius, DEFAULT_OUT_WIDTH_SCALE); + } + + public GlideBlurTransformation(Context context, float blurRadius, float outWidthScale) { + this.context = context; + this.blurRadius = blurRadius; + this.outScale = outWidthScale; + } + + @Override + protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, + int outWidth, int outHeight) { + Bitmap bitmap = super.transform(pool, toTransform, outWidth, outHeight); + Logger.d("GlideBlurTransformation", "transform=== blurRadius: " + blurRadius + " " + + "outScale: " + outScale); + return blurBitmap(bitmap, blurRadius, (int) (outWidth * outScale), (int) (outHeight * outScale)); + } + + private Bitmap blurBitmap(Bitmap bitmap, float blurRadius, int outWidth, int outHeight) { + Bitmap inputBitmap = Bitmap.createScaledBitmap(bitmap, outWidth, outHeight, false); + Bitmap outBitmap = Bitmap.createBitmap(inputBitmap); + + RenderScript renderScript = RenderScript.create(context); + ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(renderScript, + Element.U8_4(renderScript)); + Allocation tmpIn = Allocation.createFromBitmap(renderScript, inputBitmap); + Allocation tmpOut = Allocation.createFromBitmap(renderScript, outBitmap); + blurScript.setRadius(blurRadius); + blurScript.setInput(tmpIn); + blurScript.forEach(tmpOut); + tmpOut.copyTo(outBitmap); + return outBitmap; + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/glide/GlideRoundedCornersTransform.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/glide/GlideRoundedCornersTransform.java new file mode 100644 index 0000000000..7d0ad513bb --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/glide/GlideRoundedCornersTransform.java @@ -0,0 +1,169 @@ +package com.mogo.utils.glide; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapShader; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.RectF; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; +import com.bumptech.glide.load.resource.bitmap.CenterCrop; +import com.mogo.utils.BuildConfig; +import com.mogo.utils.R; + +import java.security.MessageDigest; + +/** + * Glide加载图片,使图片变成圆角图片工具 + * 基本用法Glide.with(this).load(imgUrl).apply(RequestOptions.bitmapTransform(GlideRoundedCornersTransform(this))).into(imageView) + * 如果想用多个Transform可以使用{@link com.bumptech.glide.load.MultiTransformation} 进行Transform的融合 + * @author tongchenfei + */ +public class GlideRoundedCornersTransform extends CenterCrop { + private float mRadius; + private CornerType mCornerType; + private static final int VERSION = 1; + private static final String ID = BuildConfig.LIBRARY_PACKAGE_NAME + "GlideRoundedCornersTransform." + VERSION; + private static final byte[] ID_BYTES = ID.getBytes(CHARSET); + + /** + * 待处理的圆角枚举 + */ + public enum CornerType { + ALL, + TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, + TOP, BOTTOM, LEFT, RIGHT, + TOP_LEFT_BOTTOM_RIGHT, + TOP_RIGHT_BOTTOM_LEFT, + TOP_LEFT_TOP_RIGHT_BOTTOM_RIGHT, + TOP_RIGHT_BOTTOM_RIGHT_BOTTOM_LEFT, + TOP_LEFT_TOP_RIGHT + } + + public GlideRoundedCornersTransform(float radius, CornerType cornerType) { + super(); + mRadius = radius; + mCornerType = cornerType; + } + + @Override + protected Bitmap transform(@NonNull BitmapPool pool,@NonNull Bitmap toTransform, int outWidth, int outHeight) { + Bitmap transform = super.transform(pool, toTransform, outWidth, outHeight); + return roundCrop(pool, transform); + } + + private Bitmap roundCrop(BitmapPool pool, Bitmap source) { + if (source == null) { + return null; + } + int width = source.getWidth(); + int height = source.getHeight(); + Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888); + + if (result == null) { + result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config + .ARGB_8888); + } + Canvas canvas = new Canvas(result); + Paint paint = new Paint(); + paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader + .TileMode.CLAMP)); + paint.setAntiAlias(true); + + Path path = new Path(); + drawRoundRect(canvas, paint, path, width, height); + + return result; + } + + private void drawRoundRect(Canvas canvas, Paint paint, Path path, int width, int height) { + float[] rids; + switch (mCornerType) { + case ALL: + rids = new float[]{mRadius, mRadius, mRadius, mRadius, mRadius, mRadius, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_LEFT: + rids = new float[]{mRadius, mRadius, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_RIGHT: + rids = new float[]{0.0f, 0.0f, mRadius, mRadius, 0.0f, 0.0f, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case BOTTOM_RIGHT: + rids = new float[]{0.0f, 0.0f, 0.0f, 0.0f, mRadius, mRadius, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case BOTTOM_LEFT: + rids = new float[]{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP: + rids = new float[]{mRadius, mRadius, mRadius, mRadius, 0.0f, 0.0f, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case BOTTOM: + rids = new float[]{0.0f, 0.0f, 0.0f, 0.0f, mRadius, mRadius, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case LEFT: + rids = new float[]{mRadius, mRadius, 0.0f, 0.0f, 0.0f, 0.0f, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case RIGHT: + rids = new float[]{0.0f, 0.0f, mRadius, mRadius, mRadius, mRadius, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_LEFT_BOTTOM_RIGHT: + rids = new float[]{mRadius, mRadius, 0.0f, 0.0f, mRadius, mRadius, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_RIGHT_BOTTOM_LEFT: + rids = new float[]{0.0f, 0.0f, mRadius, mRadius, 0.0f, 0.0f, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_LEFT_TOP_RIGHT_BOTTOM_RIGHT: + rids = new float[]{mRadius, mRadius, mRadius, mRadius, mRadius, mRadius, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_RIGHT_BOTTOM_RIGHT_BOTTOM_LEFT: + rids = new float[]{0.0f, 0.0f, mRadius, mRadius, mRadius, mRadius, mRadius, mRadius}; + drawPath(rids, canvas, paint, path, width, height); + break; + case TOP_LEFT_TOP_RIGHT: + rids = new float[]{mRadius, mRadius, mRadius, mRadius, 0.0f, 0.0f, 0.0f, 0.0f}; + drawPath(rids, canvas, paint, path, width, height); + break; + default: + throw new RuntimeException("RoundedCorners type not belong to CornerType"); + } + } + + /** + * @param rids 圆角的半径,依次为左上角xy半径,右上角,右下角,左下角 + */ + private void drawPath(float[] rids, Canvas canvas, Paint paint, Path path, int width, int height) { + path.addRoundRect(new RectF(0, 0, width, height), rids, Path.Direction.CW); + canvas.drawPath(path, paint); + } + + @Override + public boolean equals(Object o) { + return o instanceof GlideRoundedCornersTransform; + } + + @Override + public int hashCode() { + return ID.hashCode(); + } + + @Override + public void updateDiskCacheKey(MessageDigest messageDigest) { + messageDigest.update(ID_BYTES); + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/logger/LoggerPrinter.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/logger/LoggerPrinter.java index d4b65ba28c..0c5fc3a233 100644 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/logger/LoggerPrinter.java +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/logger/LoggerPrinter.java @@ -56,7 +56,7 @@ final class LoggerPrinter implements Printer { public void e( String tag, Throwable throwable, String message, Object... args) { if (throwable != null && message != null) { - message = message + " : " + throwable.toString(); + message = message + " : " + Log.getStackTraceString( throwable); } if (throwable != null && message == null) { diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RequestLogInterceptor.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RequestLogInterceptor.java index 5af287c703..2bb8c921ae 100644 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RequestLogInterceptor.java +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RequestLogInterceptor.java @@ -3,12 +3,15 @@ package com.mogo.utils.network; import com.mogo.utils.logger.Logger; import java.io.IOException; +import java.nio.charset.Charset; import okhttp3.Interceptor; +import okhttp3.MediaType; import okhttp3.Protocol; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; +import okio.Buffer; final class RequestLogInterceptor implements Interceptor { @@ -33,9 +36,26 @@ final class RequestLogInterceptor implements Interceptor { logMsg.append(request.url()).append("\r\n"); if(hasRequestBody){ logMsg.append("Content-Type: ").append(requestBody.contentType()).append(", "); - logMsg.append("Content-Length: ").append(requestBody.contentLength()); + logMsg.append("\r\nContent-Length: ").append(requestBody.contentLength()); + try { + String body = null; + Charset UTF8 = Charset.forName("UTF-8"); + Buffer buffer = new Buffer(); + requestBody.writeTo(buffer); + Charset charset = UTF8; + MediaType contentType = requestBody.contentType(); + if (contentType != null) { + charset = contentType.charset(UTF8); + } + if (charset != null) { + body = buffer.readString(charset); + } + logMsg.append("\r\nContent-body: ").append(body); + } catch (IOException e) { + e.printStackTrace(); + } } - logMsg.append(" <-- end http request"); + logMsg.append("\r\n<-- end http request"); if(NetConfig.instance().isLoggable()){ Logger.d(TAG, logMsg.toString()); diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RequestOptions.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RequestOptions.java index d0bae21535..d5d050cd7c 100644 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RequestOptions.java +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RequestOptions.java @@ -17,7 +17,7 @@ public class RequestOptions { private Context context; private Map< String, Object > parameter; private CharSequence loadingMessage; - private boolean loading; + private boolean loading = false; private boolean cancelable; private boolean cancelableOnTouchOutside; @@ -65,7 +65,7 @@ public class RequestOptions { /** * Mutator for indicating whether loading message should be displayed while request is ongoing */ - public RequestOptions loading( boolean loading ) { + private RequestOptions loading( boolean loading ) { this.loading = loading; return this; } @@ -73,7 +73,7 @@ public class RequestOptions { /** * Mutator for loading message */ - public RequestOptions loadingMessage( CharSequence loadingMessage ) { + private RequestOptions loadingMessage( CharSequence loadingMessage ) { this.loading = true; this.loadingMessage = loadingMessage; return this; diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RetrofitFactory.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RetrofitFactory.java index f26c1b1d74..f451d23d56 100644 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RetrofitFactory.java +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/network/RetrofitFactory.java @@ -6,29 +6,41 @@ 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 { - private static final Map< String, Retrofit> sRpcServiceMap = new ArrayMap< String,Retrofit>(); + private static final Map sRpcServiceMap = new ArrayMap(); + private static final Map sRpcNoAdapterServiceMap = new ArrayMap(); - private RetrofitFactory(){} + private RetrofitFactory() { + } - public static synchronized Retrofit getInstance( String baseUrl) { + public static synchronized Retrofit getInstance(String baseUrl) { Retrofit target = sRpcServiceMap.get(baseUrl); - - if(target == null){ + if (target == null) { target = new Retrofit.Builder(). client(OkHttpFactory.getInstance()). baseUrl(baseUrl). - addCallAdapterFactory(RxJavaCallAdapterFactory.create()). + addCallAdapterFactory(RxJava2CallAdapterFactory.create()). addConverterFactory(GsonConverterFactory.create()). build(); - sRpcServiceMap.put(baseUrl,target); + sRpcServiceMap.put(baseUrl, target); } - return target; } + public static synchronized Retrofit getInstanceNoCallAdapter(String baseUrl) { + Retrofit target = sRpcNoAdapterServiceMap.get(baseUrl); + if (target == null) { + target = new Retrofit.Builder(). + client(OkHttpFactory.getInstance()). + baseUrl(baseUrl). + addConverterFactory(GsonConverterFactory.create()). + build(); + sRpcNoAdapterServiceMap.put(baseUrl, target); + } + return target; + } } diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/network/SubscriberEx.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/network/SubscriberEx.java deleted file mode 100644 index 158c431852..0000000000 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/network/SubscriberEx.java +++ /dev/null @@ -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; - - -/** - *

- * 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.

- */ - -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 ) { - } - -} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/network/utils/GsonUtil.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/network/utils/GsonUtil.java index ea1cfad71d..540458dde6 100644 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/network/utils/GsonUtil.java +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/network/utils/GsonUtil.java @@ -36,6 +36,7 @@ public class GsonUtil { try { return getGson().toJson(object); } catch ( Exception var2) { + var2.printStackTrace(); return null; } } @@ -48,6 +49,7 @@ public class GsonUtil { try { return getGson().fromJson(json, klass); } catch ( Exception var3) { + var3.printStackTrace(); return null; } } diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/BaseDao.kt b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/BaseDao.kt new file mode 100644 index 0000000000..c755822a6b --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/BaseDao.kt @@ -0,0 +1,423 @@ +package com.mogo.utils.sqlite + +import android.content.ContentValues +import android.database.Cursor +import android.database.sqlite.SQLiteDatabase +import com.mogo.utils.sqlite.annotation.DbField +import com.mogo.utils.sqlite.annotation.DbTable +import java.lang.reflect.Field +import java.util.* + + +/** + *

数据类操作实现

+ *Created by donghongyu on 2019/9/6. + */ +//T必须指明上界是Any且不为null,下面会用到反射获取对象实例,默认是Any? +open class BaseDao : IBaseDao { + + //数据库操作的引用 + private var sqLiteDatabase: SQLiteDatabase? = null + //要操作的数据实体的引用 + private var entityClass: Class? = null + //要操作的数据表名称 + private var tableName: String? = null + //记录数据表是否存在 + private var isInit = false + + //因为反射会消耗时间,这里使用缓存,进行性能优化 + //缓存空间(key-字段名,标注的自定义注解 value-成员变量) + private var cacheField: HashMap? = null + + override fun init(sqLiteDatabase: SQLiteDatabase, entityClass: Class): Boolean { + this.sqLiteDatabase = sqLiteDatabase + this.entityClass = entityClass + //自动建表(只创建一次) + if (!isInit) { + //获取表名 + tableName = entityClass.getAnnotation(DbTable::class.java).tableName + + //如果数据库没有建立连接跳出操作防止异常信息 + if (!sqLiteDatabase.isOpen) { + return false + } + + //执行Sql进行自动建表 + val createTableSql = getCreateTableSql() + sqLiteDatabase.execSQL(createTableSql) + + //初始化缓存空间 + cacheField = HashMap() + initCacheField() + + //标记已经创建过数据表 + isInit = true + } + + return isInit + } + + /** + * 初始化字段缓存 + */ + private fun initCacheField() { + //1.取到所有的列名(查询一个空表获取表结构,不影响性能) + if (sqLiteDatabase != null && sqLiteDatabase!!.isOpen) { + val sqlQuery = "select * from $tableName limit 1,0" + val cursor = sqLiteDatabase!!.rawQuery(sqlQuery, null) + //获取所有的列名 + val columnNames = cursor.columnNames + //关闭资源 + cursor.close() + //2.取所有成员名 + val columnFields = entityClass!!.declaredFields + //3.通过两层循环,进行对应关系建立 + columnNames.forEach ColumnFor@{ columnName -> + columnFields.forEach FieldFor@{ columnField -> + if (columnName == columnField.getAnnotation(DbField::class.java).fieldName) { + columnField.isAccessible = true + cacheField!![columnName] = columnField + } + return@FieldFor + } + } + } + } + + /** + * 拼装创建数据表的SQL语句 + */ + private fun getCreateTableSql(): String? { + //create table if not exists tb_name(_id integer,name varchar2(20)) + val sqlCreateTable = StringBuffer() + sqlCreateTable.append("create table if not exists ") + sqlCreateTable.append("$tableName (") + //反射获取所有的数据对象内的成员变量 + val fields = entityClass!!.declaredFields + + fields.forEachIndexed { index, field -> + //字段名称 + val columnName = field.getAnnotation(DbField::class.java).fieldName + //获取成员变量数据类型 + + when (val fieldType = field.type) { + String::class.java -> { + sqlCreateTable.append("$columnName TEXT,") + } + Integer::class.java -> { + sqlCreateTable.append("$columnName INTEGER,") + } + Long::class.java -> { + sqlCreateTable.append("$columnName BIGINT,") + } + Double::class.java -> { + sqlCreateTable.append("$columnName DOUBLE,") + } + ByteArray::class.java -> { + sqlCreateTable.append("$columnName BLOB,") + } + else -> { + //未知类型 + throw UnsupportedOperationException("未定义的数据类型:fieldName= $columnName fieldType= $fieldType") + } + } + + if (index == fields.size - 1) { + if (sqlCreateTable.endsWith(",")) + sqlCreateTable.deleteCharAt(sqlCreateTable.length - 1) + } + } + sqlCreateTable.append(")") + + return sqlCreateTable.toString() + } + + /** + * 插入数据 + */ + override fun insert(entity: T): Long { + //1、准备好ContentValues中的数据 + //2、设置插入的内容 + val values: ContentValues = getContentValuesForInsert(entity) + //3、执行插入 + return if (sqLiteDatabase != null && sqLiteDatabase!!.isOpen) { + sqLiteDatabase!!.insert(tableName, null, values) + } else { + -1 + } + } + + /** + * 删除数据 + */ + override fun delete(where: T): Int { + val condition = Condition(getContentValuesForQuery(where)) + + return if (sqLiteDatabase != null && sqLiteDatabase!!.isOpen) { + //受影响行数 + sqLiteDatabase!! + .delete( + tableName, + condition.getWhereCause(), + condition.getWhereArgs() + ) + } else { + -1 + } + } + + /** + * 更新数据 + */ + override fun update(where: T, newEntity: T): Int { + val condition = Condition(getContentValuesForQuery(where)) + + return if (sqLiteDatabase != null && sqLiteDatabase!!.isOpen) { + //受影响行数 + sqLiteDatabase!! + .update( + tableName, + getContentValuesForInsert(newEntity), + condition.getWhereCause(), + condition.getWhereArgs() + ) + } else { + -1 + } + } + + /** + * 查询数据 + * @param where 查询条件对象,同时也用来初始化对象使用 + */ + override fun query(where: T): MutableList { + return query(where, null, null, null) + } + + /** + * 查询数据 + * @param where 查询条件对象 + * @param orderBy 排序规则 + * @param startIndex 开始的位置 + * @param limit 限制查询得到的数据个数 + */ + fun query(where: T, orderBy: String?, startIndex: Int?, limit: Int?): MutableList { + //拼接分页语句 + var limitString: String? = null + if (startIndex != null && limit != null) { + limitString = "$startIndex,$limit" + } + + val condition = Condition(getContentValuesForQuery(where)) + + var cursor: Cursor? = null + + //定义查询结果 + val result = mutableListOf() + if (sqLiteDatabase != null && sqLiteDatabase!!.isOpen) { + try { + //查询数据库 + cursor = sqLiteDatabase!! + .query( + tableName, + null, + condition.getWhereCause(), + condition.getWhereArgs(), + null, + null, + orderBy, + limitString + ) + //将查到结果添加到返回集合中 + result.addAll(getQueryResult(cursor, where)) + } catch (e: Exception) { + e.printStackTrace() + } finally { + cursor?.close() + } + } + return result + } + + /** + * 获取查询使用的ContentValues + */ + private fun getContentValuesForQuery(entity: T): ContentValues { + val contentValues = ContentValues() + try { + cacheField!!.forEach { + if (it.value.get(entity) == null) { + return@forEach + } + contentValues.put(it.key, it.value.get(entity).toString()) + } + } catch (e: IllegalAccessError) { + e.printStackTrace() + } + + return contentValues + } + + /** + * 条件拼接 + */ + class Condition(whereContent: ContentValues) { + /** + * 条件拼接 + * _id=?&&name=? + */ + private var whereCause: String? = null + + private var whereArgs: Array? = null + + //根据传入的contentValues转换成查询条件 + init { + //记录后面填充到查询语句“?”上的数据参数 + val argList = mutableListOf() + //拼接查询语句 + val whereCaseSb = StringBuilder() + + /** + * 是为了链接下面的查询条件条件,也或者是替换没有查询条件的语句。 + * 比如:要把检索条件作为一个参数传递给SQL, + * 那么,当这个检索语句不存在的话就可以给它赋值为1=1. + * 这样就避免了SQL出错,也就可以把加条件的SQL和不加条件的SQL合二为一。 + */ + whereCaseSb.append(" 1=1 ") + + val keys = whereContent.keySet() + val iterator = keys.iterator() + + //因为使用了“1=1”,所以即便是这里没有任何数据拼接,也是可以正常 + while (iterator.hasNext()) { + val key = iterator.next() as String + val valueObject = whereContent.get(key) + if (valueObject != null) { + val value = valueObject as String + //拼接查询条件语句 + //1:1 and _id=? and name=? + whereCaseSb.append(" and $key =?") + + //记录?对应的value + argList.add(value) + } + } + //集合转成数组 + this.whereArgs = argList.toTypedArray() + this.whereCause = whereCaseSb.toString() + } + + fun getWhereCause(): String { + return this.whereCause!! + } + + fun getWhereArgs(): Array { + return this.whereArgs!! + } + } + + /** + * 获取查询db结果 + */ + private fun getQueryResult(cursor: Cursor, where: T): MutableList { + //定义查询结果 + val result = mutableListOf() + //Cursor从头读到尾 + //游标从头读到尾 + cursor.moveToFirst() + //移动游标获取下一行数据 + while (!cursor.isAfterLast) { + //通过反射构建一个查询结果对象 + val item = where.javaClass.newInstance() + + //拿到缓存的当前数据对象的成员变量与数据库的键值关系 + val fieldIterator = cacheField!!.entries.iterator() + fieldIterator.forEach IteratorFor@{ + //获取数据库字段名称 + val columnName = it.key + //数据库字段名对应的数据对象的成员变量 + val field = it.value + //获取指定列名对应的索引 + val columnIndex = cursor.getColumnIndex(columnName) + //获取成员变量数据类型 + val fieldType = field.type + + if (columnIndex != -1) { + when (fieldType) { + String::class.java -> { + field.set(item, cursor.getString(columnIndex)) + } + Integer::class.java -> { + field.set(item, cursor.getInt(columnIndex)) + } + Long::class.java -> { + field.set(item, cursor.getLong(columnIndex)) + } + Double::class.java -> { + field.set(item, cursor.getDouble(columnIndex)) + } + ByteArray::class.java -> { + field.set(item, cursor.getBlob(columnIndex)) + } + else -> { + //未知类型 + throw UnsupportedOperationException("未定义的数据类型:columnName= $columnName fieldType= $fieldType") + } + } + } + } + //添加到结果集 + result.add(item) + //移动到下一个位置 + cursor.moveToNext() + } + cursor.close() + return result + } + + /** + * 获取插入使用的ContentValues + */ + private fun getContentValuesForInsert(entity: T): ContentValues { + val contentValues = ContentValues() + + val fieldIterator = cacheField!!.entries.iterator() + + fieldIterator.forEach IteratorFor@{ + try { + //获取变量的值 + val valueObject = it.value.get(entity) ?: return@IteratorFor + //获取列名 + val columnName = it.key + //获取成员变量数据类型 + val fieldType = it.value.type + when (fieldType) { + String::class.java -> { + contentValues.put(columnName, valueObject as String) + } + Integer::class.java -> { + contentValues.put(columnName, valueObject as Int) + } + Long::class.java -> { + contentValues.put(columnName, valueObject as Long) + } + Double::class.java -> { + contentValues.put(columnName, valueObject as Double) + } + ByteArray::class.java -> { + contentValues.put(columnName, valueObject as ByteArray) + } + else -> { + //未知类型 + throw UnsupportedOperationException("未定义的数据类型:columnName= $columnName fieldType= $fieldType") + } + } + } catch (e: IllegalArgumentException) { + e.printStackTrace() + } + } + + return contentValues + } + +} \ No newline at end of file diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/BaseDaoFactory.kt b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/BaseDaoFactory.kt new file mode 100644 index 0000000000..605043bf5a --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/BaseDaoFactory.kt @@ -0,0 +1,74 @@ +package com.mogo.utils.sqlite + +import android.content.Context +import android.database.sqlite.SQLiteDatabase +import com.mogo.utils.sqlite.annotation.DbDatabase +import com.mogo.utils.sqlite.proxy.BaseDaoProxyLog + + +/** + *

数据库处理工厂

+ * Created by donghongyu on 2019/9/6. + */ +open class BaseDaoFactory { + + //默认数据库名称 + private var dbName = "MoGoSQLite.db" + + companion object { + //单利工厂 + private var baseDaoFactory: BaseDaoFactory? = null + + //数据库存储路径 + private lateinit var sqLiteDatabasePath: String + + //数据库操作类 + private var sqLiteDatabase: SQLiteDatabase? = null + + fun getInstance(): BaseDaoFactory { + if (baseDaoFactory == null) { + synchronized(BaseDaoFactory::class.java) { + if (baseDaoFactory == null) { + baseDaoFactory = BaseDaoFactory() + } + } + } + return baseDaoFactory!! + } + } + + //获取数据库操作对象 + fun getBaseDao(context: Context, entityClass: Class): IBaseDao? { + var baseDao: IBaseDao? = null + + try { + //获取数据库名称,如果没有设置则使用默认名称 + val dbDatabase = entityClass.getAnnotation(DbDatabase::class.java) + if (dbDatabase != null) { + dbName = dbDatabase.dbName + } + //openOrCreateDatabase 如果不存在则先创建再打开数据库,如果存在则直接打开。 + sqLiteDatabasePath = + "${context.getDir("database", Context.MODE_APPEND).path}/$dbName" + sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(sqLiteDatabasePath, null) + + // 这里为了演示,添加了日志工具的叠加使用,根据需要可以自己修改 + // baseDao = BaseDaoProxyShow().bind(BaseDaoProxyLog().bind(BaseDao())) as IBaseDao + baseDao = BaseDaoProxyLog().bind(BaseDao()) as IBaseDao + + baseDao.init(sqLiteDatabase!!, entityClass) + } catch (e: Exception) { + e.printStackTrace() + } + + return baseDao + } + + /** + * 关闭数据库 + */ + fun closeDatabase() { + sqLiteDatabase?.close() + } + +} \ No newline at end of file diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/IBaseDao.kt b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/IBaseDao.kt new file mode 100644 index 0000000000..7af36200b8 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/IBaseDao.kt @@ -0,0 +1,35 @@ +package com.mogo.utils.sqlite + +import android.database.sqlite.SQLiteDatabase + +/** + *

操作SQLite数据库的顶层接口

+ * Created by donghongyu on 2019/9/6. + */ +interface IBaseDao { + /** + * 初始化数据库连接 + */ + fun init(sqLiteDatabase: SQLiteDatabase, entityClass: Class): Boolean + + /** + * 将 [entity] 进行数据插入 + */ + fun insert(entity: T): Long + + /** + * 根据条件 [where] 进行数据删除 + */ + fun delete(where: T): Int + + /** + * 根据条件 [where] 进行数据更新,如果[where]==null 则代表删除所有数据 + */ + fun update(where: T, newEntity: T): Int + + /** + * 根据条件 [where] 进行数据查询,如果[where]==null 则代表查询所有数据 + */ + fun query(where: T): MutableList + +} \ No newline at end of file diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/annotation/DbDatabase.kt b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/annotation/DbDatabase.kt new file mode 100644 index 0000000000..4fade720b2 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/annotation/DbDatabase.kt @@ -0,0 +1,15 @@ +package com.mogo.utils.sqlite.annotation + + +/** + *

添加在要操作的数据对象名上面,用来设置数据库名称

+ * + * /** + * * @DbDatabase("AppSQLite.db") + * * class UserEntity {} + * */ + * Created by donghongyu on 2019/9/6. + */ +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.CLASS) +annotation class DbDatabase(val dbName: String) \ No newline at end of file diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/annotation/DbField.kt b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/annotation/DbField.kt new file mode 100644 index 0000000000..cf63587d32 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/annotation/DbField.kt @@ -0,0 +1,21 @@ +package com.mogo.utils.sqlite.annotation + + +/** + *

添加在要处理的数据对象的字段之上,用来设置数据表的字段名称

+ * /** + * *@DbTable("tb_user") + * *class UserEntity { + * * @DbField("_id") + * * var id: Int = 0 + * * @DbField("name") + * * var name: String? = null + * * @DbField("password") + * * var password: String? = null + * *} + * */ + * Created by donghongyu on 2019/9/6. + */ +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.FIELD) +annotation class DbField(val fieldName: String) \ No newline at end of file diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/annotation/DbTable.kt b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/annotation/DbTable.kt new file mode 100644 index 0000000000..73aec8445f --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/annotation/DbTable.kt @@ -0,0 +1,15 @@ +package com.mogo.utils.sqlite.annotation + + +/** + *

添加在要操作的数据对象名上面,用来设置数据表名称

+ * + * /** + * * @DbTable("tb_user") + * * class UserEntity {} + * */ + * Created by donghongyu on 2019/9/6. + */ +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.CLASS) +annotation class DbTable(val tableName: String) \ No newline at end of file diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/proxy/BaseDaoProxy.kt b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/proxy/BaseDaoProxy.kt new file mode 100644 index 0000000000..f48adc9f79 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/proxy/BaseDaoProxy.kt @@ -0,0 +1,51 @@ +package com.mogo.utils.sqlite.proxy + +import android.database.sqlite.SQLiteDatabase +import android.util.Log +import com.mogo.utils.sqlite.IBaseDao + +/** + *

静态代理数据库操作类,用来记录日志

+ * Created by donghongyu on 2019/9/6. + */ +class BaseDaoProxy(var iBaseDao: IBaseDao) : IBaseDao by iBaseDao { + override fun init(sqLiteDatabase: SQLiteDatabase, entityClass: Class): Boolean { + Log.i("数据库代理", "初始化数据库连接……") + val isInitSuccess = iBaseDao.init(sqLiteDatabase, entityClass) + if (isInitSuccess) { + Log.i("数据库代理", "数据库连接成功……") + } else { + Log.e("数据库代理", "数据库连接失败……") + } + return isInitSuccess + } + + override fun insert(entity: T): Long { + Log.i("数据库代理", "开始插入数据……") + val result = iBaseDao.insert(entity) + Log.i("数据库代理", "插入数据索引位置> $result <……") + return result + } + + override fun delete(where: T): Int { + Log.i("数据库代理", "开始删除数据……") + val result = iBaseDao.delete(where) + Log.i("数据库代理", "删除了> $result <条数据……") + return result + } + + override fun update(where: T, newEntity: T): Int { + Log.i("数据库代理", "开始更新数据……") + val result = iBaseDao.update(where, newEntity) + Log.i("数据库代理", "更新了> $result <条数据……") + return result + } + + override fun query(where: T): MutableList { + Log.i("数据库代理", "开始查询数据……") + val result = iBaseDao.query(where) + Log.i("数据库代理", "查询到> ${result.size} <条数据……") + return result + } + +} \ No newline at end of file diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/proxy/BaseDaoProxyLog.kt b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/proxy/BaseDaoProxyLog.kt new file mode 100644 index 0000000000..d65dd810dd --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/proxy/BaseDaoProxyLog.kt @@ -0,0 +1,50 @@ +package com.mogo.utils.sqlite.proxy + +import android.util.Log +import java.lang.reflect.InvocationHandler +import java.lang.reflect.Method +import java.lang.reflect.Proxy + +/** + * 使用java实现动态代理数据库操作类加入日志功能 + * Created by donghongyu on 2019/9/6. + */ + +class BaseDaoProxyLog : InvocationHandler { + + private var target: Any? = null + + /** + * 绑定委托对象并返回一个【代理占位】 + * + * @param target 真实对象 + * @return 代理对象【占位】 + */ + fun bind(target: Any): Any { + this.target = target + //取得代理对象 + return Proxy.newProxyInstance( + target.javaClass.classLoader, + target.javaClass.interfaces, this + ) + } + + /** + * 同过代理对象调用方法首先进入这个方法. + * + * @param proxy --代理对象 + * @param method -- 方法,被调用方法. + * @param args -- 方法的参数 + */ + @Throws(Throwable::class) + override fun invoke(proxy: Any, method: Method, args: Array): Any? { + var result: Any? = null + //反射方法前调用 + Log.i("数据库代理", "当前执行>>${method.name}") + //反射执行方法 相当于调用target.sayHelllo; + result = method.invoke(target, *args) + //反射方法后调用. + Log.i("数据库代理", "执行结果>>$result") + return result + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/proxy/BaseDaoProxyShow.kt b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/proxy/BaseDaoProxyShow.kt new file mode 100644 index 0000000000..d924191ba1 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/sqlite/proxy/BaseDaoProxyShow.kt @@ -0,0 +1,49 @@ +package com.mogo.utils.sqlite.proxy + +import android.util.Log +import java.lang.reflect.InvocationHandler +import java.lang.reflect.Method +import java.lang.reflect.Proxy + +/** + * 使用java实现动态代理数据库操作类,加入更多额外的功能,来测试代理类的叠加功能 + * Created by donghongyu on 2019/9/6. + */ +class BaseDaoProxyShow : InvocationHandler { + + private var target: Any? = null + + /** + * 绑定委托对象并返回一个【代理占位】 + * + * @param target 真实对象 + * @return 代理对象【占位】 + */ + fun bind(target: Any): Any { + this.target = target + //取得代理对象 + return Proxy.newProxyInstance( + target.javaClass.classLoader, + target.javaClass.interfaces, this + ) + } + + /** + * 同过代理对象调用方法首先进入这个方法. + * + * @param proxy --代理对象 + * @param method -- 方法,被调用方法. + * @param args -- 方法的参数 + */ + @Throws(Throwable::class) + override fun invoke(proxy: Any, method: Method, args: Array): Any? { + var result: Any? = null + //反射方法前调用 + Log.i("数据库代理", "显示执行>>${method.name}") + //反射执行方法 相当于调用target.sayHelllo; + result = method.invoke(target, *args) + //反射方法后调用. + Log.i("数据库代理", "执行结果>>$result") + return result + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/Eyes.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/Eyes.java new file mode 100644 index 0000000000..b0eecffd79 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/Eyes.java @@ -0,0 +1,177 @@ +package com.mogo.utils.statusbar; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Color; +import android.os.Build; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import androidx.core.view.ViewCompat; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class Eyes { + + + public static void setStatusBarColor( Activity activity, int statusColor ) { + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { + EyesLollipop.setStatusBarColor( activity, statusColor ); + } else if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ) { + EyesKitKat.setStatusBarColor( activity, statusColor ); + } + } + + public static void translucentStatusBar( Activity activity ) { + translucentStatusBar( activity, false ); + } + + public static void translucentStatusBar( Activity activity, boolean hideStatusBarBackground ) { + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { + EyesLollipop.translucentStatusBar( activity, hideStatusBarBackground ); + } else if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ) { + EyesKitKat.translucentStatusBar( activity ); + } + } +// +// public static void setStatusBarColorForCollapsingToolbar(@NonNull Activity activity, AppBarLayout appBarLayout, CollapsingToolbarLayout collapsingToolbarLayout, +// Toolbar toolbar, @ColorInt int statusColor) { +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { +// EyesLollipop.setStatusBarColorForCollapsingToolbar(activity, appBarLayout, collapsingToolbarLayout, toolbar, statusColor); +// } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { +// EyesKitKat.setStatusBarColorForCollapsingToolbar(activity, appBarLayout, collapsingToolbarLayout, toolbar, statusColor); +// } +// } + + public static void setStatusBarLightMode( Activity activity, int color ) { + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ) { + //判断是否为小米或魅族手机,如果是则将状态栏文字改为黑色 + if ( MIUISetStatusBarLightMode( activity, true ) || FlymeSetStatusBarLightMode( activity, true ) ) { + //设置状态栏为指定颜色 + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) {//5.0 + activity.getWindow().setStatusBarColor( color ); + } else {//4.4 + //调用修改状态栏颜色的方法 + setStatusBarColor( activity, color ); + } + } else if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) { + //如果是6.0以上将状态栏文字改为黑色,并设置状态栏颜色 + activity.getWindow().setBackgroundDrawableResource( android.R.color.transparent ); + activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR ); + activity.getWindow().setStatusBarColor( color ); + + //fitsSystemWindow 为 false, 不预留系统栏位置. + ViewGroup mContentView = activity.getWindow().findViewById( Window.ID_ANDROID_CONTENT ); + View mChildView = mContentView.getChildAt( 0 ); + if ( mChildView != null ) { + mChildView.setFitsSystemWindows( true ); + ViewCompat.requestApplyInsets( mChildView ); + } + } + } + } + +// +// public static void setStatusBarLightForCollapsingToolbar(Activity activity, AppBarLayout appBarLayout, +// CollapsingToolbarLayout collapsingToolbarLayout, Toolbar toolbar, int statusBarColor) { +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { +// EyesLollipop.setStatusBarWhiteForCollapsingToolbar(activity, appBarLayout, collapsingToolbarLayout, toolbar, statusBarColor); +// } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { +// EyesKitKat.setStatusBarWhiteForCollapsingToolbar(activity, appBarLayout, collapsingToolbarLayout, toolbar, statusBarColor); +// } +// } + + + /** + * MIUI的沉浸支持透明白色字体和透明黑色字体 + * https://dev.mi.com/console/doc/detail?pId=1159 + */ + static boolean MIUISetStatusBarLightMode( Activity activity, boolean darkmode ) { + try { + Class< ? > layoutParams = Class.forName( "android.view.MiuiWindowManager$LayoutParams" ); + + Window window = activity.getWindow(); + window.addFlags( WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS ); + window.clearFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS ); + window.getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR ); + + Class< ? extends Window> clazz = activity.getWindow().getClass(); + Field field = layoutParams.getField( "EXTRA_FLAG_STATUS_BAR_DARK_MODE" ); + int darkModeFlag = field.getInt( layoutParams ); + Method extraFlagField = clazz.getMethod( "setExtraFlags", int.class, int.class ); + extraFlagField.invoke( activity.getWindow(), darkmode ? darkModeFlag : 0, darkModeFlag ); + return true; + } catch ( Exception e ) { + } + return false; + } + + /** + * 设置状态栏图标为深色和魅族特定的文字风格,Flyme4.0以上 + */ + static boolean FlymeSetStatusBarLightMode( Activity activity, boolean darkmode ) { + try { + WindowManager.LayoutParams lp = activity.getWindow().getAttributes(); + Field darkFlag = WindowManager.LayoutParams.class + .getDeclaredField( "MEIZU_FLAG_DARK_STATUS_BAR_ICON" ); + Field meizuFlags = WindowManager.LayoutParams.class + .getDeclaredField( "meizuFlags" ); + darkFlag.setAccessible( true ); + meizuFlags.setAccessible( true ); + int bit = darkFlag.getInt( null ); + int value = meizuFlags.getInt( lp ); + if ( darkmode ) { + value |= bit; + } else { + value &= ~bit; + } + meizuFlags.setInt( lp, value ); + activity.getWindow().setAttributes( lp ); + return true; + } catch ( Exception e ) { + } + return false; + } + + static void setContentTopPadding( Activity activity, int padding ) { + ViewGroup mContentView = activity.getWindow().findViewById( Window.ID_ANDROID_CONTENT ); + mContentView.setPadding( 0, padding, 0, 0 ); + } + + static int getPxFromDp( Context context, float dp ) { + return ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics() ); + } + + /** + * 设置状态栏颜色 + * + * @param activity + * @param isBlackText true黑色 false 白字 + */ + public static void setStatusBarStyle( Activity activity, boolean isBlackText, boolean isFitSystem ) { + setStatusBarStyle( activity, isBlackText, isBlackText ? Color.WHITE : Color.TRANSPARENT, isFitSystem ); + } + + public static void setStatusBarStyle( Activity activity, boolean isBlackText, int statusBarBgColor, boolean isFitSystem ) { + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { + activity.getWindow().setBackgroundDrawableResource( android.R.color.transparent ); + if ( isBlackText ) { + activity.getWindow().getDecorView().setSystemUiVisibility( ( isFitSystem ? View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : View.SYSTEM_UI_FLAG_VISIBLE ) | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR ); + } else { + activity.getWindow().getDecorView().setSystemUiVisibility( ( isFitSystem ? View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : View.SYSTEM_UI_FLAG_VISIBLE ) ); + } + activity.getWindow().setStatusBarColor( statusBarBgColor ); + } + } + + + public static void setMessageFragmentStatus( Activity activity ) { + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { + activity.getWindow().setBackgroundDrawableResource( android.R.color.transparent ); + activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR ); + } + } + +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesKitKat.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesKitKat.java new file mode 100644 index 0000000000..c922602529 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesKitKat.java @@ -0,0 +1,277 @@ +package com.mogo.utils.statusbar; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.Context; +import android.os.Build; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.FrameLayout; +import com.mogo.utils.R; + +@TargetApi( Build.VERSION_CODES.KITKAT ) +class EyesKitKat { + private static final String TAG_FAKE_STATUS_BAR_VIEW = "statusBarView"; + private static final String TAG_MARGIN_ADDED = "marginAdded"; + + static void setStatusBarColor( Activity activity, int statusColor ) { + Window window = activity.getWindow(); + //设置Window为全透明 + window.addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS ); + + ViewGroup mContentView = window.findViewById( Window.ID_ANDROID_CONTENT ); + //获取父布局 + View mContentChild = mContentView.getChildAt( 0 ); + //获取状态栏高度 + int statusBarHeight = getStatusBarHeight( activity ); + + //如果已经存在假状态栏则移除,防止重复添加 + removeFakeStatusBarViewIfExist( activity ); + //添加一个View来作为状态栏的填充 + addFakeStatusBarView( activity, statusColor, statusBarHeight ); + //设置子控件到状态栏的间距 + addMarginTopToContentChild( mContentChild, statusBarHeight ); + //不预留系统栏位置 + if ( mContentChild != null ) { + mContentChild.setFitsSystemWindows( false ); + } + //如果在Activity中使用了ActionBar则需要再将布局与状态栏的高度跳高一个ActionBar的高度,否则内容会被ActionBar遮挡 + int action_bar_id = activity.getResources().getIdentifier( "action_bar", "id", activity.getPackageName() ); + View view = activity.findViewById( action_bar_id ); + if ( view != null ) { + TypedValue typedValue = new TypedValue(); + if ( activity.getTheme().resolveAttribute( R.attr.actionBarSize, typedValue, true ) ) { + int actionBarHeight = TypedValue.complexToDimensionPixelSize( typedValue.data, activity.getResources().getDisplayMetrics() ); + Eyes.setContentTopPadding( activity, actionBarHeight ); + } + } + } + + static void translucentStatusBar( Activity activity ) { + Window window = activity.getWindow(); + //设置Window为透明 + window.addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS ); + + ViewGroup mContentView = activity.findViewById( Window.ID_ANDROID_CONTENT ); + View mContentChild = mContentView.getChildAt( 0 ); + + //移除已经存在假状态栏则,并且取消它的Margin间距 + removeFakeStatusBarViewIfExist( activity ); + removeMarginTopOfContentChild( mContentChild, getStatusBarHeight( activity ) ); + if ( mContentChild != null ) { + //fitsSystemWindow 为 false, 不预留系统栏位置. + mContentChild.setFitsSystemWindows( false ); + } + } + +// static void setStatusBarColorForCollapsingToolbar( final Activity activity, final AppBarLayout appBarLayout, final CollapsingToolbarLayout collapsingToolbarLayout, +// Toolbar toolbar, int statusColor ) { +// Window window = activity.getWindow(); +// //设置Window为全透明 +// window.addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS ); +// ViewGroup mContentView = window.findViewById( Window.ID_ANDROID_CONTENT ); +// +// //AppBarLayout,CollapsingToolbarLayout,ToolBar,ImageView的fitsSystemWindow统一改为false, 不预留系统栏位置. +// View mContentChild = mContentView.getChildAt( 0 ); +// mContentChild.setFitsSystemWindows( false ); +// ( ( View ) appBarLayout.getParent() ).setFitsSystemWindows( false ); +// appBarLayout.setFitsSystemWindows( false ); +// collapsingToolbarLayout.setFitsSystemWindows( false ); +// collapsingToolbarLayout.getChildAt( 0 ).setFitsSystemWindows( false ); +// +// toolbar.setFitsSystemWindows( false ); +// //为Toolbar添加一个状态栏的高度, 同时为Toolbar添加paddingTop,使Toolbar覆盖状态栏,ToolBar的title可以正常显示. +// if ( toolbar.getTag() == null ) { +// CollapsingToolbarLayout.LayoutParams lp = ( CollapsingToolbarLayout.LayoutParams ) toolbar.getLayoutParams(); +// int statusBarHeight = getStatusBarHeight( activity ); +// lp.height += statusBarHeight; +// toolbar.setLayoutParams( lp ); +// toolbar.setPadding( toolbar.getPaddingLeft(), toolbar.getPaddingTop() + statusBarHeight, toolbar.getPaddingRight(), toolbar.getPaddingBottom() ); +// toolbar.setTag( true ); +// } +// //移除已经存在假状态栏则,并且取消它的Margin间距 +// int statusBarHeight = getStatusBarHeight( activity ); +// removeFakeStatusBarViewIfExist( activity ); +// removeMarginTopOfContentChild( mContentChild, statusBarHeight ); +// //添加一个View来作为状态栏的填充 +// final View statusView = addFakeStatusBarView( activity, statusColor, statusBarHeight ); +// +// CoordinatorLayout.Behavior behavior = ( ( CoordinatorLayout.LayoutParams ) appBarLayout.getLayoutParams() ).getBehavior(); +// if ( behavior != null && behavior instanceof AppBarLayout.Behavior ) { +// int verticalOffset = ( ( AppBarLayout.Behavior ) behavior ).getTopAndBottomOffset(); +// if ( Math.abs( verticalOffset ) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger() ) { +// statusView.setAlpha( 1f ); +// } else { +// statusView.setAlpha( 0f ); +// } +// } else { +// statusView.setAlpha( 0f ); +// } +// appBarLayout.addOnOffsetChangedListener( new AppBarLayout.OnOffsetChangedListener() { +// @Override +// public void onOffsetChanged( AppBarLayout appBarLayout, int verticalOffset ) { +// if ( Math.abs( verticalOffset ) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger() ) { +// //toolbar被折叠时显示状态栏 +// if ( statusView.getAlpha() == 0 ) { +// statusView.animate().cancel(); +// statusView.animate().alpha( 1f ).setDuration( collapsingToolbarLayout.getScrimAnimationDuration() ).start(); +// } +// } else { +// //toolbar展开时显示状态栏 +// if ( statusView.getAlpha() == 1 ) { +// statusView.animate().cancel(); +// statusView.animate().alpha( 0f ).setDuration( collapsingToolbarLayout.getScrimAnimationDuration() ).start(); +// } +// } +// } +// } ); +// } +// +// static void setStatusBarWhiteForCollapsingToolbar( final Activity activity, AppBarLayout appBarLayout, final CollapsingToolbarLayout collapsingToolbarLayout, Toolbar toolbar, final int statusBarColor ) { +// final Window window = activity.getWindow(); +// window.addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS ); +// +// ViewGroup mContentView = window.findViewById( Window.ID_ANDROID_CONTENT ); +// View mContentChild = mContentView.getChildAt( 0 ); +// mContentChild.setFitsSystemWindows( false ); +// ( ( View ) appBarLayout.getParent() ).setFitsSystemWindows( false ); +// appBarLayout.setFitsSystemWindows( false ); +// collapsingToolbarLayout.setFitsSystemWindows( false ); +// collapsingToolbarLayout.getChildAt( 0 ).setFitsSystemWindows( false ); +// toolbar.setFitsSystemWindows( false ); +// +// if ( toolbar.getTag() == null ) { +// CollapsingToolbarLayout.LayoutParams lp = ( CollapsingToolbarLayout.LayoutParams ) toolbar.getLayoutParams(); +// int statusBarHeight = getStatusBarHeight( activity ); +// lp.height += statusBarHeight; +// toolbar.setLayoutParams( lp ); +// toolbar.setPadding( toolbar.getPaddingLeft(), toolbar.getPaddingTop() + statusBarHeight, toolbar.getPaddingRight(), toolbar.getPaddingBottom() ); +// toolbar.setTag( true ); +// } +// +// int statusBarHeight = getStatusBarHeight( activity ); +// int color = Color.BLACK; +// try { +// Class< ? > layoutParams = Class.forName( "android.view.MiuiWindowManager$LayoutParams" ); +// color = statusBarColor; +// } catch ( ClassNotFoundException e ) { +// e.printStackTrace(); +// } +// try { +// Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField( "MEIZU_FLAG_DARK_STATUS_BAR_ICON" ); +// color = statusBarColor; +// } catch ( NoSuchFieldException e ) { +// e.printStackTrace(); +// } +// final View statusView = addFakeStatusBarView( activity, color, statusBarHeight ); +// CoordinatorLayout.Behavior behavior = ( ( CoordinatorLayout.LayoutParams ) appBarLayout.getLayoutParams() ).getBehavior(); +// if ( behavior != null && behavior instanceof AppBarLayout.Behavior ) { +// int verticalOffset = ( ( AppBarLayout.Behavior ) behavior ).getTopAndBottomOffset(); +// if ( Math.abs( verticalOffset ) > appBarLayout.getHeight() - collapsingToolbarLayout.getScrimVisibleHeightTrigger() ) { +// statusView.setAlpha( 1f ); +// } else { +// statusView.setAlpha( 0f ); +// } +// } else { +// statusView.setAlpha( 0f ); +// } +// +// appBarLayout.addOnOffsetChangedListener( new AppBarLayout.OnOffsetChangedListener() { +// private final static int EXPANDED = 0; +// private final static int COLLAPSED = 1; +// private int appBarLayoutState; +// +// @Override +// public void onOffsetChanged( AppBarLayout appBarLayout, int verticalOffset ) { +// if ( Math.abs( verticalOffset ) >= ( appBarLayout.getTotalScrollRange() - Eyes.getPxFromDp( activity, 56 ) ) ) { +// if ( appBarLayoutState != COLLAPSED ) { +// appBarLayoutState = COLLAPSED; +// +// if ( Eyes.MIUISetStatusBarLightMode( activity, true ) || Eyes.FlymeSetStatusBarLightMode( activity, true ) ) { +// } +// if ( statusView.getAlpha() == 0 ) { +// statusView.animate().cancel(); +// statusView.animate().alpha( 1f ).setDuration( collapsingToolbarLayout.getScrimAnimationDuration() ).start(); +// } +// } +// } else { +// if ( appBarLayoutState != EXPANDED ) { +// appBarLayoutState = EXPANDED; +// +// if ( Eyes.MIUISetStatusBarLightMode( activity, false ) || Eyes.FlymeSetStatusBarLightMode( activity, false ) ) { +// } +// if ( statusView.getAlpha() == 1 ) { +// statusView.animate().cancel(); +// statusView.animate().alpha( 0f ).setDuration( collapsingToolbarLayout.getScrimAnimationDuration() ).start(); +// } +// translucentStatusBar( activity ); +// } +// } +// } +// } ); +// } + + private static void removeFakeStatusBarViewIfExist( Activity activity ) { + Window window = activity.getWindow(); + ViewGroup mDecorView = (ViewGroup) window.getDecorView(); + + View fakeView = mDecorView.findViewWithTag( TAG_FAKE_STATUS_BAR_VIEW ); + if ( fakeView != null ) { + mDecorView.removeView( fakeView ); + } + } + + private static View addFakeStatusBarView( Activity activity, int statusBarColor, int statusBarHeight ) { + Window window = activity.getWindow(); + ViewGroup mDecorView = (ViewGroup) window.getDecorView(); + + View mStatusBarView = new View( activity ); + FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight ); + layoutParams.gravity = Gravity.TOP; + mStatusBarView.setLayoutParams( layoutParams ); + mStatusBarView.setBackgroundColor( statusBarColor ); + mStatusBarView.setTag( TAG_FAKE_STATUS_BAR_VIEW ); + + mDecorView.addView( mStatusBarView ); + return mStatusBarView; + } + + private static void addMarginTopToContentChild( View mContentChild, int statusBarHeight ) { + if ( mContentChild == null ) { + return; + } + if ( !TAG_MARGIN_ADDED.equals( mContentChild.getTag() ) ) { + FrameLayout.LayoutParams lp = ( FrameLayout.LayoutParams ) mContentChild.getLayoutParams(); + lp.topMargin += statusBarHeight; + mContentChild.setLayoutParams( lp ); + mContentChild.setTag( TAG_MARGIN_ADDED ); + } + } + + private static int getStatusBarHeight( Context context ) { + int result = 0; + int resId = context.getResources().getIdentifier( "status_bar_height", "dimen", "android" ); + if ( resId > 0 ) { + result = context.getResources().getDimensionPixelOffset( resId ); + } + return result; + } + + private static void removeMarginTopOfContentChild( View mContentChild, int statusBarHeight ) { + if ( mContentChild == null ) { + return; + } + if ( TAG_MARGIN_ADDED.equals( mContentChild.getTag() ) ) { + FrameLayout.LayoutParams lp = ( FrameLayout.LayoutParams ) mContentChild.getLayoutParams(); + lp.topMargin -= statusBarHeight; + mContentChild.setLayoutParams( lp ); + mContentChild.setTag( null ); + } + } + + +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesLollipop.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesLollipop.java new file mode 100644 index 0000000000..f7426867ca --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/statusbar/EyesLollipop.java @@ -0,0 +1,219 @@ +package com.mogo.utils.statusbar; + + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.Context; +import android.graphics.Color; +import android.os.Build; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import androidx.core.view.ViewCompat; + +@TargetApi(Build.VERSION_CODES.LOLLIPOP) +class EyesLollipop { + + static void setStatusBarColor(Activity activity, int statusColor) { + Window window = activity.getWindow(); + //取消状态栏透明 + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + //添加Flag把状态栏设为可绘制模式 + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + //设置状态栏颜色 + window.setStatusBarColor(statusColor); + //设置系统状态栏处于可见状态 + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + //让view不根据系统窗口来调整自己的布局 + ViewGroup mContentView = window.findViewById(Window.ID_ANDROID_CONTENT); + View mChildView = mContentView.getChildAt(0); + if (mChildView != null) { + mChildView.setFitsSystemWindows(false); + ViewCompat.requestApplyInsets(mChildView); + } + } + + static void translucentStatusBar(Activity activity, boolean hideStatusBarBackground) { + Window window = activity.getWindow(); + //添加Flag把状态栏设为可绘制模式 + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + if (hideStatusBarBackground) { + //如果为全透明模式,取消设置Window半透明的Flag + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + //设置状态栏为透明 + window.setStatusBarColor(Color.TRANSPARENT); + //设置window的状态栏不可见 + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + } else { + //如果为半透明模式,添加设置Window半透明的Flag + window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + //设置系统状态栏处于可见状态 + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + } + //view不根据系统窗口来调整自己的布局 + ViewGroup mContentView = window.findViewById(Window.ID_ANDROID_CONTENT); + View mChildView = mContentView.getChildAt(0); + if (mChildView != null) { + mChildView.setFitsSystemWindows(false); + ViewCompat.requestApplyInsets(mChildView); + } + } + +// static void setStatusBarColorForCollapsingToolbar(final Activity activity, final AppBarLayout appBarLayout, final CollapsingToolbarLayout collapsingToolbarLayout, +// Toolbar toolbar, final int statusColor) { +// final Window window = activity.getWindow(); +// //取消设置Window半透明的Flag +// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); +// ////添加Flag把状态栏设为可绘制模式 +// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); +// //设置状态栏为透明 +// window.setStatusBarColor(Color.TRANSPARENT); +// //设置系统状态栏处于可见状态 +// window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); +// //通过OnApplyWindowInsetsListener()使Layout在绘制过程中将View向下偏移了,使collapsingToolbarLayout可以占据状态栏 +// ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout, new OnApplyWindowInsetsListener() { +// @Override +// public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { +// return insets; +// } +// }); +// +// ViewGroup mContentView = window.findViewById(Window.ID_ANDROID_CONTENT); +// View mChildView = mContentView.getChildAt(0); +// //view不根据系统窗口来调整自己的布局 +// if (mChildView != null) { +// mChildView.setFitsSystemWindows(false); +// ViewCompat.requestApplyInsets(mChildView); +// } +// +// ((View) appBarLayout.getParent()).setFitsSystemWindows(false); +// appBarLayout.setFitsSystemWindows(false); +// collapsingToolbarLayout.setFitsSystemWindows(false); +// collapsingToolbarLayout.getChildAt(0).setFitsSystemWindows(false); +// //设置状态栏的颜色 +// collapsingToolbarLayout.setStatusBarScrimColor(statusColor); +// toolbar.setFitsSystemWindows(false); +// //为Toolbar添加一个状态栏的高度, 同时为Toolbar添加paddingTop,使Toolbar覆盖状态栏,ToolBar的title可以正常显示. +// if (toolbar.getTag() == null) { +// CollapsingToolbarLayout.LayoutParams lp = (CollapsingToolbarLayout.LayoutParams) toolbar.getLayoutParams(); +// int statusBarHeight = getStatusBarHeight(activity); +// lp.height += statusBarHeight; +// toolbar.setLayoutParams(lp); +// toolbar.setPadding(toolbar.getPaddingLeft(), toolbar.getPaddingTop() + statusBarHeight, toolbar.getPaddingRight(), toolbar.getPaddingBottom()); +// toolbar.setTag(true); +// } +// +// appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { +// private final static int EXPANDED = 0; +// private final static int COLLAPSED = 1; +// private int appBarLayoutState; +// +// @Override +// public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { +// //toolbar被折叠时显示状态栏 +// if (Math.abs(verticalOffset) > collapsingToolbarLayout.getScrimVisibleHeightTrigger()) { +// if (appBarLayoutState != COLLAPSED) { +// appBarLayoutState = COLLAPSED;//修改状态标记为折叠 +// setStatusBarColor(activity, statusColor); +// } +// } else { +// //toolbar显示时同时显示状态栏 +// if (appBarLayoutState != EXPANDED) { +// appBarLayoutState = EXPANDED;//修改状态标记为展开 +// translucentStatusBar(activity, true); +// } +// } +// } +// }); +// } +// +// static void setStatusBarWhiteForCollapsingToolbar(final Activity activity, final AppBarLayout appBarLayout, final CollapsingToolbarLayout collapsingToolbarLayout, final Toolbar toolbar, final int statusBarColor) { +// final Window window = activity.getWindow(); +// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); +// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); +// window.setStatusBarColor(Color.TRANSPARENT); +// window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); +// +// ViewCompat.setOnApplyWindowInsetsListener(collapsingToolbarLayout, new OnApplyWindowInsetsListener() { +// @Override +// public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { +// return insets; +// } +// }); +// +// ViewGroup mContentView = window.findViewById(Window.ID_ANDROID_CONTENT); +// View mChildView = mContentView.getChildAt(0); +// if (mChildView != null) { +// mChildView.setFitsSystemWindows(false); +// ViewCompat.requestApplyInsets(mChildView); +// } +// +// ((View) appBarLayout.getParent()).setFitsSystemWindows(false); +// appBarLayout.setFitsSystemWindows(false); +// toolbar.setFitsSystemWindows(false); +// if (toolbar.getTag() == null) { +// CollapsingToolbarLayout.LayoutParams lp = (CollapsingToolbarLayout.LayoutParams) toolbar.getLayoutParams(); +// int statusBarHeight = getStatusBarHeight(activity); +// lp.height += statusBarHeight; +// toolbar.setLayoutParams(lp); +// toolbar.setPadding(toolbar.getPaddingLeft(), toolbar.getPaddingTop() + statusBarHeight, toolbar.getPaddingRight(), toolbar.getPaddingBottom()); +// toolbar.setTag(true); +// } +// +// collapsingToolbarLayout.setFitsSystemWindows(false); +// collapsingToolbarLayout.getChildAt(0).setFitsSystemWindows(false); +// collapsingToolbarLayout.setStatusBarScrimColor(statusBarColor); +// appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { +// private final static int EXPANDED = 0; +// private final static int COLLAPSED = 1; +// private int appBarLayoutState; +// +// @Override +// public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { +// //toolbar被折叠时显示状态栏 +// if (Math.abs(verticalOffset) > collapsingToolbarLayout.getScrimVisibleHeightTrigger()) { +// if (appBarLayoutState != COLLAPSED) { +// appBarLayoutState = COLLAPSED;//修改状态标记为折叠 +// +// //先判断是否为小米设备,设置状态栏不成功判断是否为6.0以上设备,不是6.0以上设备再判断是否为魅族设备,不是魅族设备就只设置状态栏颜色 +// if (Eyes.MIUISetStatusBarLightMode(activity, true)) { +// return; +// } +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { +// activity.getWindow().setBackgroundDrawableResource(android.R.color.transparent); +// activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); +// activity.getWindow().setStatusBarColor(statusBarColor); +// } else if (!Eyes.FlymeSetStatusBarLightMode(activity, true)) { +// setStatusBarColor(activity, statusBarColor); +// } +// } +// } else { +// //toolbar显示时同时显示状态栏 +// if (appBarLayoutState != EXPANDED) { +// appBarLayoutState = EXPANDED;//修改状态标记为展开 +// +// if (Eyes.MIUISetStatusBarLightMode(activity, false)) { +// translucentStatusBar(activity, true); +// return; +// } +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { +// activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE); +// } else if (Eyes.FlymeSetStatusBarLightMode(activity, true)) { +// } +// translucentStatusBar(activity, true); +// } +// } +// } +// }); +// } + + private static int getStatusBarHeight(Context context) { + int result = 0; + int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resId > 0) { + result = context.getResources().getDimensionPixelOffset(resId); + } + return result; + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/SharedPrefsMgr.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/SharedPrefsMgr.java index 3acfd14fa3..7dfc30da3d 100644 --- a/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/SharedPrefsMgr.java +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/SharedPrefsMgr.java @@ -5,6 +5,8 @@ import android.content.SharedPreferences; import androidx.annotation.NonNull; +import java.util.Set; + public class SharedPrefsMgr { private static final String File_Name = "app_shared_pref"; @@ -128,4 +130,17 @@ public class SharedPrefsMgr { } } + public void putStringSet( String key, Set< String > values ) { + try { + SharedPreferences.Editor editor = sSharedPrefs.edit(); + editor.putStringSet( key, values ); + editor.apply(); + } catch ( Exception e ) { + } + } + + public Set getStringSet( String key ) { + return sSharedPrefs.getStringSet( key, null ); + } + } \ No newline at end of file diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/CacheUtil.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/CacheUtil.java new file mode 100644 index 0000000000..ca7c761c06 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/CacheUtil.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mogo.utils.storage.lrucache; + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.io.StringWriter; +import java.nio.charset.Charset; + +/** Junk drawer of utility methods. */ +final class CacheUtil { + static final Charset US_ASCII = Charset.forName("US-ASCII"); + static final Charset UTF_8 = Charset.forName("UTF-8"); + + private CacheUtil() { + } + + static String readFully( Reader reader) throws IOException { + try { + StringWriter writer = new StringWriter(); + char[] buffer = new char[1024]; + int count; + while ((count = reader.read(buffer)) != -1) { + writer.write(buffer, 0, count); + } + return writer.toString(); + } finally { + reader.close(); + } + } + + /** + * Deletes the imageContent of {@code dir}. Throws an IOException if any file + * could not be deleted, or if {@code dir} is not a readable directory. + */ + static void deleteContents( File dir) throws IOException { + File[] files = dir.listFiles(); + if (files == null) { + throw new IOException("not a readable directory: " + dir); + } + for ( File file : files) { + if (file.isDirectory()) { + deleteContents(file); + } + if (!file.delete()) { + throw new IOException("failed to delete file: " + file); + } + } + } + + static void closeQuietly(/*Auto*/Closeable closeable) { + if (closeable != null) { + try { + closeable.close(); + } catch ( RuntimeException rethrown) { + throw rethrown; + } catch ( Exception ignored) { + } + } + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/DiskCacheManager.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/DiskCacheManager.java new file mode 100644 index 0000000000..a37aa56d37 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/DiskCacheManager.java @@ -0,0 +1,374 @@ +package com.mogo.utils.storage.lrucache; + +import android.content.Context; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Serializable; + +public class DiskCacheManager { + + private static DiskLruCache mDiskLruCache = null; + private DiskLruCache.Editor mEditor = null; + private DiskLruCache.Snapshot mSnapshot = null; + public static final long CACHE_MAXSIZE = 10 * 1024 * 1024; + + public DiskCacheManager( Context context, String uniqueName) { + try { + if (mDiskLruCache != null) { + mDiskLruCache.close(); + mDiskLruCache = null; + } + File cacheFile = getCacheFile(context, uniqueName); + mDiskLruCache = DiskLruCache.open(cacheFile, 1, 1, CACHE_MAXSIZE); + } catch ( IOException e) { + e.printStackTrace(); + } + } + + /** + * 获取缓存的路径 两个路径在卸载程序时都会删除,因此不会在卸载后还保留乱七八糟的缓存 + * 有SD卡时获取 /sdcard/Android/data//cache + * 无SD卡时获取 /data/labelList//cache + * + * @param context 上下文 + * @param uniqueName 缓存目录下的细分目录,用于存放不同类型的缓存 + * @return 缓存目录 File + */ + private File getCacheFile( Context context, String uniqueName) { + String cachePath = null; + try { + cachePath = context.getCacheDir().getPath(); + }catch ( Exception e){ + e.printStackTrace(); + } + return new File(cachePath + File.separator + uniqueName); + } + + /** + * 获取缓存 editor + * + * @param key 缓存的key + * @return editor + * @throws IOException + */ + private DiskLruCache.Editor edit( String key) throws IOException { + key = SecretUtil.getMD5Result(key); //存取的 key + if (mDiskLruCache != null) { + mEditor = mDiskLruCache.edit(key); + } + return mEditor; + } + + /** + * 根据 key 获取缓存缩略 + * + * @param key 缓存的key + * @return Snapshot + */ + private DiskLruCache.Snapshot snapshot( String key) { + if (mDiskLruCache != null) { + try { + mSnapshot = mDiskLruCache.get(key); + } catch ( IOException e) { + e.printStackTrace(); + } + } + return mSnapshot; + } + /************************* + * 字符串读写 + *************************/ + /** + * 缓存 String + * + * @param key 缓存文件键值(MD5加密结果作为缓存文件名) + * @param value 缓存内容 + */ + public void put( String key, String value) { + DiskLruCache.Editor editor = null; + BufferedWriter writer = null; + try { + editor = edit(key); + if (editor == null) { + return; + } + OutputStream os = editor.newOutputStream(0); + writer = new BufferedWriter(new OutputStreamWriter(os)); + writer.write(value); + editor.commit(); + } catch ( IOException e) { + e.printStackTrace(); + try { + if (editor != null) + editor.abort(); + } catch ( IOException e1) { + e1.printStackTrace(); + } + } finally { + try { + if (writer != null) { + writer.close(); + } + } catch ( IOException e) { + e.printStackTrace(); + } + } + } + + /** + * 获取字符串缓存 + * + * @param key cache'key + * @return string + */ + public String getString( String key) { + InputStream inputStream = getCacheInputStream(key); + if (inputStream == null) { + return null; + } + try { + return inputStream2String(inputStream); + } catch ( IOException e) { + e.printStackTrace(); + return null; + } finally { + try { + inputStream.close(); + } catch ( IOException e1) { + e1.printStackTrace(); + } + } + } + + /************************* + * Json对象读写 + *************************/ + //Json 数据转换成 String 存储 + public void put( String key, JSONObject value) { + put(key, value.toString()); + } + + //取得 json 字符串再转为 Json对象 + public JSONObject getJsonObject( String key) { + String json = getString(key); + try { + return new JSONObject(json); + } catch ( JSONException e) { + e.printStackTrace(); + return null; + } + } + + /************************* + * Json数组对象读写 + *************************/ + + public void put( String key, JSONArray array) { + put(key, array.toString()); + } + + public JSONArray getJsonArray( String key) { + try { + return new JSONArray(getString(key)); + } catch ( JSONException e) { + e.printStackTrace(); + return null; + } + } + + /************************* + * byte 数据读写 + *************************/ + /** + * 存入byte数组 + * + * @param key cache'key + * @param bytes bytes to save + */ + public void put( String key, byte[] bytes) { + OutputStream out = null; + DiskLruCache.Editor editor = null; + try { + editor = edit(key); + if (editor == null) { + return; + } + out = editor.newOutputStream(0); + out.write(bytes); + out.flush(); + editor.commit(); + } catch ( IOException e) { + e.printStackTrace(); + try { + if (editor != null) { + editor.abort(); + } + } catch ( IOException e1) { + e1.printStackTrace(); + } + } finally { + if (out != null) { + try { + out.close(); + } catch ( IOException e) { + e.printStackTrace(); + } + } + } + } + + /** + * 获取缓存的 byte 数组 + * + * @param key cache'key + * @return bytes + */ + public byte[] getBytes( String key) { + byte[] bytes = null; + InputStream inputStream = getCacheInputStream(key); + if (inputStream == null) { + return null; + } + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buf = new byte[256]; + int len = 0; + try { + while ((len = inputStream.read(buf)) != -1) { + bos.write(buf, 0, len); + } + bytes = bos.toByteArray(); + } catch ( IOException e) { + e.printStackTrace(); + } + return bytes; + } + + /************************* + * 序列化对象数据读写 + *************************/ + + /** + * 序列化对象写入 + * + * @param key cache'key + * @param object 待缓存的序列化对象 + */ + public void put( String key, Serializable object) { + ObjectOutputStream oos = null; + DiskLruCache.Editor editor = null; + try { + editor = edit(key); + if (editor == null) { + return; + } + oos = new ObjectOutputStream(editor.newOutputStream(0)); + oos.writeObject(object); + oos.flush(); + editor.commit(); + } catch ( IOException e) { + e.printStackTrace(); + try { + if (editor != null) + editor.abort(); + } catch ( IOException e1) { + e1.printStackTrace(); + } + } finally { + try { + if (oos != null) { + oos.close(); + } + } catch ( IOException e) { + e.printStackTrace(); + } + } + } + + /** + * 获取 序列化对象 + * + * @param key cache'key + * @param 对象类型 + * @return 读取到的序列化对象 + */ + @SuppressWarnings("unchecked") + public T getSerializable( String key) { + T object = null; + ObjectInputStream ois = null; + InputStream in = getCacheInputStream(key); + if (in == null) { + return null; + } + try { + ois = new ObjectInputStream(in); + object = (T) ois.readObject(); + } catch ( IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + return object; + } + + + /************************************************************************ + ********************** 辅助工具方法 分割线 **************************** + ************************************************************************/ + /** + * inputStream 转 String + * + * @param is 输入流 + * @return 结果字符串 + */ + private String inputStream2String( InputStream is) throws IOException { + BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8")); + StringBuilder buffer = new StringBuilder(); + String line; + while ((line = in.readLine()) != null) { + buffer.append(line); + } + return buffer.toString(); + } + + /** + * 获取 缓存数据的 InputStream + * + * @param key cache'key + * @return InputStream + */ + private InputStream getCacheInputStream( String key) { + key = SecretUtil.getMD5Result(key); + InputStream in; + DiskLruCache.Snapshot snapshot = snapshot(key); + if (snapshot == null) { + return null; + } + in = snapshot.getInputStream(0); + return in; + } + + /** + * 同步记录文件 + */ + public static void flush() { + if (mDiskLruCache != null) { + try { + mDiskLruCache.flush(); + } catch ( IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/DiskLruCache.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/DiskLruCache.java new file mode 100644 index 0000000000..72db55be4d --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/DiskLruCache.java @@ -0,0 +1,947 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mogo.utils.storage.lrucache; + +import java.io.BufferedWriter; +import java.io.Closeable; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A cache that uses a bounded amount of space on a filesystem. Each cache + * entry has a string key and a fixed number of values. Each key must match + * the regex [a-z0-9_-]{1,120}. Values are byte sequences, + * accessible as streams or files. Each value must be between {@code 0} and + * {@code Integer.MAX_VALUE} bytes in length. + * + *

The cache stores its data in a directory on the filesystem. This + * directory must be exclusive to the cache; the cache may delete or overwrite + * files from its directory. It is an error for multiple processes to use the + * same cache directory at the same time. + * + *

This cache limits the number of bytes that it will store on the + * filesystem. When the number of stored bytes exceeds the limit, the cache will + * remove entries in the background until the limit is satisfied. The limit is + * not strict: the cache may temporarily exceed it while waiting for files to be + * deleted. The limit does not include filesystem overhead or the cache + * journal so space-sensitive applications should set a conservative limit. + * + *

Clients call {@link #edit} to create or update the values of an entry. An + * entry may have only one editor at one time; if a value is not available to be + * edited then {@link #edit} will return null. + *

    + *
  • When an entry is being created it is necessary to + * supply a full set of values; the empty value should be used as a + * placeholder if necessary. + *
  • When an entry is being edited, it is not necessary + * to supply data for every value; values default to their previous + * value. + *
+ * Every {@link #edit} call must be matched by a call to {@link Editor#commit} + * or {@link Editor#abort}. Committing is atomic: a read observes the full set + * of values as they were before or after the commit, but never a mix of values. + * + *

Clients call {@link #get} to read a snapshot of an entry. The read will + * observe the value at the time that {@link #get} was called. Updates and + * removals after the call do not impact ongoing reads. + * + *

This class is tolerant of some I/O errors. If files are missing from the + * filesystem, the corresponding entries will be dropped from the cache. If + * an error occurs while writing a cache value, the edit will fail silently. + * Callers should handle other problems by catching {@code IOException} and + * responding appropriately. + */ +public final class DiskLruCache implements Closeable { + static final String JOURNAL_FILE = "journal"; + static final String JOURNAL_FILE_TEMP = "journal.tmp"; + static final String JOURNAL_FILE_BACKUP = "journal.bkp"; + static final String MAGIC = "libcore.io.DiskLruCache"; + static final String VERSION_1 = "1"; + static final long ANY_SEQUENCE_NUMBER = -1; + static final String STRING_KEY_PATTERN = "[a-z0-9_-]{1,120}"; + static final Pattern LEGAL_KEY_PATTERN = Pattern.compile(STRING_KEY_PATTERN); + private static final String CLEAN = "CLEAN"; + private static final String DIRTY = "DIRTY"; + private static final String REMOVE = "REMOVE"; + private static final String READ = "READ"; + + /* + * This cache uses a journal file named "journal". A typical journal file + * looks like this: + * libcore.io.DiskLruCache + * 1 + * 100 + * 2 + * + * CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054 + * DIRTY 335c4c6028171cfddfbaae1a9c313c52 + * CLEAN 335c4c6028171cfddfbaae1a9c313c52 3934 2342 + * REMOVE 335c4c6028171cfddfbaae1a9c313c52 + * DIRTY 1ab96a171faeeee38496d8b330771a7a + * CLEAN 1ab96a171faeeee38496d8b330771a7a 1600 234 + * READ 335c4c6028171cfddfbaae1a9c313c52 + * READ 3400330d1dfc7f3f7f4b8d4d803dfcf6 + * + * The first five lines of the journal form its header. They are the + * constant string "libcore.io.DiskLruCache", the disk cache's version, + * the application's version, the value count, and a blank line. + * + * Each of the subsequent lines in the file is a record of the state of a + * cache entry. Each line contains space-separated values: a state, a key, + * and optional state-specific values. + * o DIRTY lines track that an entry is actively being created or updated. + * Every successful DIRTY action should be followed by a CLEAN or REMOVE + * action. DIRTY lines without a matching CLEAN or REMOVE indicate that + * temporary files may need to be deleted. + * o CLEAN lines track a cache entry that has been successfully published + * and may be read. A publish line is followed by the lengths of each of + * its values. + * o READ lines track accesses for LRU. + * o REMOVE lines track entries that have been deleted. + * + * The journal file is appended to as cache operations occur. The journal may + * occasionally be compacted by dropping redundant lines. A temporary file named + * "journal.tmp" will be used during compaction; that file should be deleted if + * it exists when the cache is opened. + */ + + private final File directory; + private final File journalFile; + private final File journalFileTmp; + private final File journalFileBackup; + private final int appVersion; + private long maxSize; + private final int valueCount; + private long size = 0; + private Writer journalWriter; + private final LinkedHashMap< String, Entry> lruEntries = + new LinkedHashMap< String, Entry>(0, 0.75f, true); + private int redundantOpCount; + + /** + * To differentiate between old and current snapshots, each entry is given + * a sequence number each time an edit is committed. A snapshot is stale if + * its sequence number is not equal to its entry's sequence number. + */ + private long nextSequenceNumber = 0; + + /** This cache uses a single background thread to evict entries. */ + final ThreadPoolExecutor executorService = + new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue< Runnable >()); + private final Callable< Void > cleanupCallable = new Callable< Void >() { + public Void call() throws Exception { + synchronized (DiskLruCache.this) { + if (journalWriter == null) { + return null; // Closed. + } + trimToSize(); + if (journalRebuildRequired()) { + rebuildJournal(); + redundantOpCount = 0; + } + } + return null; + } + }; + + private DiskLruCache( File directory, int appVersion, int valueCount, long maxSize) { + this.directory = directory; + this.appVersion = appVersion; + this.journalFile = new File(directory, JOURNAL_FILE); + this.journalFileTmp = new File(directory, JOURNAL_FILE_TEMP); + this.journalFileBackup = new File(directory, JOURNAL_FILE_BACKUP); + this.valueCount = valueCount; + this.maxSize = maxSize; + } + + /** + * Opens the cache in {@code directory}, creating a cache if none exists + * there. + * + * @param directory a writable directory + * @param valueCount the number of values per cache entry. Must be positive. + * @param maxSize the maximum number of bytes this cache should use to store + * @throws IOException if reading or writing the cache directory fails + */ + public static DiskLruCache open( File directory, int appVersion, int valueCount, long maxSize) + throws IOException { + if (maxSize <= 0) { + throw new IllegalArgumentException("maxSize <= 0"); + } + if (valueCount <= 0) { + throw new IllegalArgumentException("valueCount <= 0"); + } + + // If a bkp file exists, use it instead. + File backupFile = new File(directory, JOURNAL_FILE_BACKUP); + if (backupFile.exists()) { + File journalFile = new File(directory, JOURNAL_FILE); + // If journal file also exists just delete backup file. + if (journalFile.exists()) { + backupFile.delete(); + } else { + renameTo(backupFile, journalFile, false); + } + } + + // Prefer to pick up where we left off. + DiskLruCache cache = new DiskLruCache(directory, appVersion, valueCount, maxSize); + if (cache.journalFile.exists()) { + try { + cache.readJournal(); + cache.processJournal(); + return cache; + } catch ( IOException journalIsCorrupt) { + System.out + .println("DiskLruCache " + + directory + + " is corrupt: " + + journalIsCorrupt.getMessage() + + ", removing"); + cache.delete(); + } + } + + // Create a new empty cache. + directory.mkdirs(); + cache = new DiskLruCache(directory, appVersion, valueCount, maxSize); + cache.rebuildJournal(); + return cache; + } + + private void readJournal() throws IOException { + StrictLineReader reader = new StrictLineReader(new FileInputStream(journalFile), CacheUtil.US_ASCII); + try { + String magic = reader.readLine(); + String version = reader.readLine(); + String appVersionString = reader.readLine(); + String valueCountString = reader.readLine(); + String blank = reader.readLine(); + if (!MAGIC.equals(magic) + || !VERSION_1.equals(version) + || !Integer.toString(appVersion).equals(appVersionString) + || !Integer.toString(valueCount).equals(valueCountString) + || !"".equals(blank)) { + throw new IOException("unexpected journal header: [" + magic + ", " + version + ", " + + valueCountString + ", " + blank + "]"); + } + + int lineCount = 0; + while (true) { + try { + readJournalLine(reader.readLine()); + lineCount++; + } catch ( EOFException endOfJournal) { + break; + } + } + redundantOpCount = lineCount - lruEntries.size(); + + // If we ended on a truncated line, rebuild the journal before appending to it. + if (reader.hasUnterminatedLine()) { + rebuildJournal(); + } else { + journalWriter = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(journalFile, true), CacheUtil.US_ASCII)); + } + } finally { + CacheUtil.closeQuietly(reader); + } + } + + private void readJournalLine( String line) throws IOException { + int firstSpace = line.indexOf(' '); + if (firstSpace == -1) { + throw new IOException("unexpected journal line: " + line); + } + + int keyBegin = firstSpace + 1; + int secondSpace = line.indexOf(' ', keyBegin); + final String key; + if (secondSpace == -1) { + key = line.substring(keyBegin); + if (firstSpace == REMOVE.length() && line.startsWith(REMOVE)) { + lruEntries.remove(key); + return; + } + } else { + key = line.substring(keyBegin, secondSpace); + } + + Entry entry = lruEntries.get(key); + if (entry == null) { + entry = new Entry(key); + lruEntries.put(key, entry); + } + + if (secondSpace != -1 && firstSpace == CLEAN.length() && line.startsWith(CLEAN)) { + String[] parts = line.substring(secondSpace + 1).split(" "); + entry.readable = true; + entry.currentEditor = null; + entry.setLengths(parts); + } else if (secondSpace == -1 && firstSpace == DIRTY.length() && line.startsWith(DIRTY)) { + entry.currentEditor = new Editor(entry); + } else if (secondSpace == -1 && firstSpace == READ.length() && line.startsWith(READ)) { + // This work was already done by calling lruEntries.get(). + } else { + throw new IOException("unexpected journal line: " + line); + } + } + + /** + * Computes the initial size and collects garbage as a part of opening the + * cache. Dirty entries are assumed to be inconsistent and will be deleted. + */ + private void processJournal() throws IOException { + deleteIfExists(journalFileTmp); + for ( Iterator i = lruEntries.values().iterator(); i.hasNext(); ) { + Entry entry = i.next(); + if (entry.currentEditor == null) { + for (int t = 0; t < valueCount; t++) { + size += entry.lengths[t]; + } + } else { + entry.currentEditor = null; + for (int t = 0; t < valueCount; t++) { + deleteIfExists(entry.getCleanFile(t)); + deleteIfExists(entry.getDirtyFile(t)); + } + i.remove(); + } + } + } + + /** + * Creates a new journal that omits redundant information. This replaces the + * current journal if it exists. + */ + private synchronized void rebuildJournal() throws IOException { + if (journalWriter != null) { + journalWriter.close(); + } + + Writer writer = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(journalFileTmp), CacheUtil.US_ASCII)); + try { + writer.write(MAGIC); + writer.write("\n"); + writer.write(VERSION_1); + writer.write("\n"); + writer.write( Integer.toString(appVersion)); + writer.write("\n"); + writer.write( Integer.toString(valueCount)); + writer.write("\n"); + writer.write("\n"); + + for (Entry entry : lruEntries.values()) { + if (entry.currentEditor != null) { + writer.write(DIRTY + ' ' + entry.key + '\n'); + } else { + writer.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n'); + } + } + } finally { + writer.close(); + } + + if (journalFile.exists()) { + renameTo(journalFile, journalFileBackup, true); + } + renameTo(journalFileTmp, journalFile, false); + journalFileBackup.delete(); + + journalWriter = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(journalFile, true), CacheUtil.US_ASCII)); + } + + private static void deleteIfExists( File file) throws IOException { + if (file.exists() && !file.delete()) { + throw new IOException(); + } + } + + private static void renameTo( File from, File to, boolean deleteDestination) throws IOException { + if (deleteDestination) { + deleteIfExists(to); + } + if (!from.renameTo(to)) { + throw new IOException(); + } + } + + /** + * Returns a snapshot of the entry named {@code key}, or null if it doesn't + * exist is not currently readable. If a value is returned, it is moved to + * the head of the LRU queue. + */ + public synchronized Snapshot get( String key) throws IOException { + checkNotClosed(); + validateKey(key); + Entry entry = lruEntries.get(key); + if (entry == null) { + return null; + } + + if (!entry.readable) { + return null; + } + + // Open all streams eagerly to guarantee that we see a single published + // snapshot. If we opened streams lazily then the streams could come + // from different edits. + InputStream[] ins = new InputStream[valueCount]; + try { + for (int i = 0; i < valueCount; i++) { + ins[i] = new FileInputStream(entry.getCleanFile(i)); + } + } catch ( FileNotFoundException e) { + // A file must have been deleted manually! + for (int i = 0; i < valueCount; i++) { + if (ins[i] != null) { + CacheUtil.closeQuietly(ins[i]); + } else { + break; + } + } + return null; + } + + redundantOpCount++; + journalWriter.append(READ + ' ' + key + '\n'); + if (journalRebuildRequired()) { + executorService.submit(cleanupCallable); + } + + return new Snapshot(key, entry.sequenceNumber, ins, entry.lengths); + } + + /** + * Returns an editor for the entry named {@code key}, or null if another + * edit is in progress. + */ + public Editor edit( String key) throws IOException { + return edit(key, ANY_SEQUENCE_NUMBER); + } + + private synchronized Editor edit( String key, long expectedSequenceNumber) throws IOException { + checkNotClosed(); + validateKey(key); + Entry entry = lruEntries.get(key); + if (expectedSequenceNumber != ANY_SEQUENCE_NUMBER && (entry == null + || entry.sequenceNumber != expectedSequenceNumber)) { + return null; // Snapshot is stale. + } + if (entry == null) { + entry = new Entry(key); + lruEntries.put(key, entry); + } else if (entry.currentEditor != null) { + return null; // Another edit is in progress. + } + + Editor editor = new Editor(entry); + entry.currentEditor = editor; + + // Flush the journal before creating files to prevent file leaks. + journalWriter.write(DIRTY + ' ' + key + '\n'); + journalWriter.flush(); + return editor; + } + + /** Returns the directory where this cache stores its data. */ + public File getDirectory() { + return directory; + } + + /** + * Returns the maximum number of bytes that this cache should use to store + * its data. + */ + public synchronized long getMaxSize() { + return maxSize; + } + + /** + * Changes the maximum number of bytes the cache can store and queues a job + * to trim the existing store, if necessary. + */ + public synchronized void setMaxSize(long maxSize) { + this.maxSize = maxSize; + executorService.submit(cleanupCallable); + } + + /** + * Returns the number of bytes currently being used to store the values in + * this cache. This may be greater than the max size if a background + * deletion is pending. + */ + public synchronized long size() { + return size; + } + + private synchronized void completeEdit(Editor editor, boolean success) throws IOException { + Entry entry = editor.entry; + if (entry.currentEditor != editor) { + throw new IllegalStateException(); + } + + // If this edit is creating the entry for the first time, every index must have a value. + if (success && !entry.readable) { + for (int i = 0; i < valueCount; i++) { + if (!editor.written[i]) { + editor.abort(); + throw new IllegalStateException("Newly created entry didn't create value for index " + i); + } + if (!entry.getDirtyFile(i).exists()) { + editor.abort(); + return; + } + } + } + + for (int i = 0; i < valueCount; i++) { + File dirty = entry.getDirtyFile(i); + if (success) { + if (dirty.exists()) { + File clean = entry.getCleanFile(i); + dirty.renameTo(clean); + long oldLength = entry.lengths[i]; + long newLength = clean.length(); + entry.lengths[i] = newLength; + size = size - oldLength + newLength; + } + } else { + deleteIfExists(dirty); + } + } + + redundantOpCount++; + entry.currentEditor = null; + if (entry.readable | success) { + entry.readable = true; + journalWriter.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n'); + if (success) { + entry.sequenceNumber = nextSequenceNumber++; + } + } else { + lruEntries.remove(entry.key); + journalWriter.write(REMOVE + ' ' + entry.key + '\n'); + } + journalWriter.flush(); + + if (size > maxSize || journalRebuildRequired()) { + executorService.submit(cleanupCallable); + } + } + + /** + * We only rebuild the journal when it will halve the size of the journal + * and eliminate at least 2000 ops. + */ + private boolean journalRebuildRequired() { + final int redundantOpCompactThreshold = 2000; + return redundantOpCount >= redundantOpCompactThreshold // + && redundantOpCount >= lruEntries.size(); + } + + /** + * Drops the entry for {@code key} if it exists and can be removed. Entries + * actively being edited cannot be removed. + * + * @return true if an entry was removed. + */ + public synchronized boolean remove( String key) throws IOException { + checkNotClosed(); + validateKey(key); + Entry entry = lruEntries.get(key); + if (entry == null || entry.currentEditor != null) { + return false; + } + + for (int i = 0; i < valueCount; i++) { + File file = entry.getCleanFile(i); + if (file.exists() && !file.delete()) { + throw new IOException("failed to delete " + file); + } + size -= entry.lengths[i]; + entry.lengths[i] = 0; + } + + redundantOpCount++; + journalWriter.append(REMOVE + ' ' + key + '\n'); + lruEntries.remove(key); + + if (journalRebuildRequired()) { + executorService.submit(cleanupCallable); + } + + return true; + } + + /** Returns true if this cache has been closed. */ + public synchronized boolean isClosed() { + return journalWriter == null; + } + + private void checkNotClosed() { + if (journalWriter == null) { + throw new IllegalStateException("cache is closed"); + } + } + + /** Force buffered operations to the filesystem. */ + public synchronized void flush() throws IOException { + checkNotClosed(); + trimToSize(); + journalWriter.flush(); + } + + /** Closes this cache. Stored values will remain on the filesystem. */ + public synchronized void close() throws IOException { + if (journalWriter == null) { + return; // Already closed. + } + for (Entry entry : new ArrayList(lruEntries.values())) { + if (entry.currentEditor != null) { + entry.currentEditor.abort(); + } + } + trimToSize(); + journalWriter.close(); + journalWriter = null; + } + + private void trimToSize() throws IOException { + while (size > maxSize) { + Map.Entry< String, Entry> toEvict = lruEntries.entrySet().iterator().next(); + remove(toEvict.getKey()); + } + } + + /** + * Closes the cache and deletes all of its stored values. This will delete + * all files in the cache directory including files that weren't created by + * the cache. + */ + public void delete() throws IOException { + close(); + CacheUtil.deleteContents(directory); + } + + private void validateKey( String key) { + Matcher matcher = LEGAL_KEY_PATTERN.matcher(key); + if (!matcher.matches()) { + throw new IllegalArgumentException("keys must match regex " + + STRING_KEY_PATTERN + ": \"" + key + "\""); + } + } + + private static String inputStreamToString( InputStream in) throws IOException { + return CacheUtil.readFully(new InputStreamReader(in, CacheUtil.UTF_8)); + } + + /** A snapshot of the values for an entry. */ + public final class Snapshot implements Closeable { + private final String key; + private final long sequenceNumber; + private final InputStream[] ins; + private final long[] lengths; + + private Snapshot( String key, long sequenceNumber, InputStream[] ins, long[] lengths) { + this.key = key; + this.sequenceNumber = sequenceNumber; + this.ins = ins; + this.lengths = lengths; + } + + /** + * Returns an editor for this snapshot's entry, or null if either the + * entry has changed since this snapshot was created or if another edit + * is in progress. + */ + public Editor edit() throws IOException { + return DiskLruCache.this.edit(key, sequenceNumber); + } + + /** Returns the unbuffered stream with the value for {@code index}. */ + public InputStream getInputStream( int index) { + return ins[index]; + } + + /** Returns the string value for {@code index}. */ + public String getString( int index) throws IOException { + return inputStreamToString(getInputStream(index)); + } + + /** Returns the byte length of the value for {@code index}. */ + public long getLength(int index) { + return lengths[index]; + } + + public void close() { + for ( InputStream in : ins) { + CacheUtil.closeQuietly(in); + } + } + } + + private static final OutputStream NULL_OUTPUT_STREAM = new OutputStream() { + @Override + public void write(int b) throws IOException { + // Eat all writes silently. Nom nom. + } + }; + + /** Edits the values for an entry. */ + public final class Editor { + private final Entry entry; + private final boolean[] written; + private boolean hasErrors; + private boolean committed; + + private Editor(Entry entry) { + this.entry = entry; + this.written = (entry.readable) ? null : new boolean[valueCount]; + } + + /** + * Returns an unbuffered input stream to read the last committed value, + * or null if no value has been committed. + */ + public InputStream newInputStream( int index) throws IOException { + synchronized (DiskLruCache.this) { + if (entry.currentEditor != this) { + throw new IllegalStateException(); + } + if (!entry.readable) { + return null; + } + try { + return new FileInputStream(entry.getCleanFile(index)); + } catch ( FileNotFoundException e) { + return null; + } + } + } + + /** + * Returns the last committed value as a string, or null if no value + * has been committed. + */ + public String getString( int index) throws IOException { + InputStream in = newInputStream(index); + return in != null ? inputStreamToString(in) : null; + } + + /** + * Returns a new unbuffered output stream to write the value at + * {@code index}. If the underlying output stream encounters errors + * when writing to the filesystem, this edit will be aborted when + * {@link #commit} is called. The returned output stream does not throw + * IOExceptions. + */ + public OutputStream newOutputStream( int index) throws IOException { + if (index < 0 || index >= valueCount) { + throw new IllegalArgumentException("Expected index " + index + " to " + + "be greater than 0 and less than the maximum value count " + + "of " + valueCount); + } + synchronized (DiskLruCache.this) { + if (entry.currentEditor != this) { + throw new IllegalStateException(); + } + if (!entry.readable) { + written[index] = true; + } + File dirtyFile = entry.getDirtyFile(index); + FileOutputStream outputStream; + try { + outputStream = new FileOutputStream(dirtyFile); + } catch ( FileNotFoundException e) { + // Attempt to recreate the cache directory. + directory.mkdirs(); + try { + outputStream = new FileOutputStream(dirtyFile); + } catch ( FileNotFoundException e2) { + // We are unable to recover. Silently eat the writes. + return NULL_OUTPUT_STREAM; + } + } + return new FaultHidingOutputStream(outputStream); + } + } + + /** Sets the value at {@code index} to {@code value}. */ + public void set(int index, String value) throws IOException { + Writer writer = null; + try { + writer = new OutputStreamWriter(newOutputStream(index), CacheUtil.UTF_8); + writer.write(value); + } finally { + CacheUtil.closeQuietly(writer); + } + } + + /** + * Commits this edit so it is visible to readers. This releases the + * edit lock so another edit may be started on the same key. + */ + public void commit() throws IOException { + if (hasErrors) { + completeEdit(this, false); + remove(entry.key); // The previous entry is stale. + } else { + completeEdit(this, true); + } + committed = true; + } + + /** + * Aborts this edit. This releases the edit lock so another edit may be + * started on the same key. + */ + public void abort() throws IOException { + completeEdit(this, false); + } + + public void abortUnlessCommitted() { + if (!committed) { + try { + abort(); + } catch ( IOException ignored) { + } + } + } + + private class FaultHidingOutputStream extends FilterOutputStream { + private FaultHidingOutputStream( OutputStream out) { + super(out); + } + + @Override + public void write( int oneByte) { + try { + out.write(oneByte); + } catch ( IOException e) { + hasErrors = true; + } + } + + @Override + public void write( byte[] buffer, int offset, int length) { + try { + out.write(buffer, offset, length); + } catch ( IOException e) { + hasErrors = true; + } + } + + @Override + public void close() { + try { + out.close(); + } catch ( IOException e) { + hasErrors = true; + } + } + + @Override + public void flush() { + try { + out.flush(); + } catch ( IOException e) { + hasErrors = true; + } + } + } + } + + private final class Entry { + private final String key; + + /** Lengths of this entry's files. */ + private final long[] lengths; + + /** True if this entry has ever been published. */ + private boolean readable; + + /** The ongoing edit or null if this entry is not being edited. */ + private Editor currentEditor; + + /** The sequence number of the most recently committed edit to this entry. */ + private long sequenceNumber; + + private Entry( String key) { + this.key = key; + this.lengths = new long[valueCount]; + } + + public String getLengths() throws IOException { + StringBuilder result = new StringBuilder(); + for (long size : lengths) { + result.append(' ').append(size); + } + return result.toString(); + } + + /** Set lengths using decimal numbers like "10123". */ + private void setLengths( String[] strings) throws IOException { + if (strings.length != valueCount) { + throw invalidLengths(strings); + } + + try { + for (int i = 0; i < strings.length; i++) { + lengths[i] = Long.parseLong(strings[i]); + } + } catch ( NumberFormatException e) { + throw invalidLengths(strings); + } + } + + private IOException invalidLengths( String[] strings) throws IOException { + throw new IOException("unexpected journal line: " + java.util.Arrays.toString(strings)); + } + + public File getCleanFile( int i) { + return new File(directory, key + "." + i); + } + + public File getDirtyFile( int i) { + return new File(directory, key + "." + i + ".tmp"); + } + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/SecretUtil.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/SecretUtil.java new file mode 100644 index 0000000000..dc833b9d79 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/SecretUtil.java @@ -0,0 +1,34 @@ +package com.mogo.utils.storage.lrucache; +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class SecretUtil { + + public static String getMD5Result( String value) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(value.getBytes("UTF-8")); + byte[] result = md.digest(); + return getString(result); + } catch ( NoSuchAlgorithmException e) { + e.printStackTrace(); + return ""; + } catch ( UnsupportedEncodingException e) { + e.printStackTrace(); + return ""; + } + } + + private static String getString( byte[] result) { + StringBuilder sb = new StringBuilder(); + for (byte b : result) { + int i = b & 0xff; + if (i <= 0xf) { + sb.append(0); + } + sb.append( Integer.toHexString(i)); + } + return sb.toString().toLowerCase(); + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/StrictLineReader.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/StrictLineReader.java new file mode 100644 index 0000000000..5ee84ab744 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/storage/lrucache/StrictLineReader.java @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mogo.utils.storage.lrucache; + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; + +/** + * Buffers input from an {@link InputStream} for reading lines. + * + *

This class is used for buffered reading of lines. For purposes of this class, a line ends + * with "\n" or "\r\n". End of input is reported by throwing {@code EOFException}. Unterminated + * line at end of input is invalid and will be ignored, the caller may use {@code + * hasUnterminatedLine()} to detect it after catching the {@code EOFException}. + * + *

This class is intended for reading input that strictly consists of lines, such as line-based + * cache entries or cache journal. Unlike the {@link java.io.BufferedReader} which in conjunction + * with {@link java.io.InputStreamReader} provides similar functionality, this class uses different + * end-of-input reporting and a more restrictive definition of a line. + * + *

This class supports only charsets that encode '\r' and '\n' as a single byte with value 13 + * and 10, respectively, and the representation of no other character contains these values. + * We currently check in constructor that the charset is one of US-ASCII, UTF-8 and ISO-8859-1. + * The default charset is US_ASCII. + */ +class StrictLineReader implements Closeable { + private static final byte CR = (byte) '\r'; + private static final byte LF = (byte) '\n'; + + private final InputStream in; + private final Charset charset; + + /* + * Buffered data is stored in {@code buf}. As long as no exception occurs, 0 <= pos <= end + * and the data in the range [pos, end) is buffered for reading. At end of input, if there is + * an unterminated line, we set end == -1, otherwise end == pos. If the underlying + * {@code InputStream} throws an {@code IOException}, end may remain as either pos or -1. + */ + private byte[] buf; + private int pos; + private int end; + + /** + * Constructs a new {@code LineReader} with the specified charset and the default capacity. + * + * @param in the {@code InputStream} to read data from. + * @param charset the charset used to decode data. Only US-ASCII, UTF-8 and ISO-8859-1 are + * supported. + * @throws NullPointerException if {@code in} or {@code charset} is null. + * @throws IllegalArgumentException if the specified charset is not supported. + */ + public StrictLineReader( InputStream in, Charset charset) { + this(in, 8192, charset); + } + + /** + * Constructs a new {@code LineReader} with the specified capacity and charset. + * + * @param in the {@code InputStream} to read data from. + * @param capacity the capacity of the buffer. + * @param charset the charset used to decode data. Only US-ASCII, UTF-8 and ISO-8859-1 are + * supported. + * @throws NullPointerException if {@code in} or {@code charset} is null. + * @throws IllegalArgumentException if {@code capacity} is negative or zero + * or the specified charset is not supported. + */ + public StrictLineReader( InputStream in, int capacity, Charset charset) { + if (in == null || charset == null) { + throw new NullPointerException(); + } + if (capacity < 0) { + throw new IllegalArgumentException("capacity <= 0"); + } + if (!(charset.equals(CacheUtil.US_ASCII))) { + throw new IllegalArgumentException("Unsupported encoding"); + } + + this.in = in; + this.charset = charset; + buf = new byte[capacity]; + } + + /** + * Closes the reader by closing the underlying {@code InputStream} and + * marking this reader as closed. + * + * @throws IOException for errors when closing the underlying {@code InputStream}. + */ + public void close() throws IOException { + synchronized (in) { + if (buf != null) { + buf = null; + in.close(); + } + } + } + + /** + * Reads the next line. A line ends with {@code "\n"} or {@code "\r\n"}, + * this end of line marker is not included in the result. + * + * @return the next line from the input. + * @throws IOException for underlying {@code InputStream} errors. + * @throws EOFException for the end of source stream. + */ + public String readLine() throws IOException { + synchronized (in) { + if (buf == null) { + throw new IOException("LineReader is closed"); + } + + // Read more data if we are at the end of the buffered labelList. + // Though it's an error to read after an exception, we will let {@code fillBuf()} + // throw again if that happens; thus we need to handle end == -1 as well as end == pos. + if (pos >= end) { + fillBuf(); + } + // Try to find LF in the buffered data and return the line if successful. + for (int i = pos; i != end; ++i) { + if (buf[i] == LF) { + int lineEnd = (i != pos && buf[i - 1] == CR) ? i - 1 : i; + String res = new String(buf, pos, lineEnd - pos, charset.name()); + pos = i + 1; + return res; + } + } + + // Let's anticipate up to 80 characters on top of those already read. + ByteArrayOutputStream out = new ByteArrayOutputStream(end - pos + 80) { + @Override + public String toString() { + int length = (count > 0 && buf[count - 1] == CR) ? count - 1 : count; + try { + return new String(buf, 0, length, charset.name()); + } catch ( UnsupportedEncodingException e) { + throw new AssertionError(e); // Since we control the charset this will never happen. + } + } + }; + + while (true) { + out.write(buf, pos, end - pos); + // Mark unterminated line in case fillBuf throws EOFException or IOException. + end = -1; + fillBuf(); + // Try to find LF in the buffered data and return the line if successful. + for (int i = pos; i != end; ++i) { + if (buf[i] == LF) { + if (i != pos) { + out.write(buf, pos, i - pos); + } + pos = i + 1; + return out.toString(); + } + } + } + } + } + + public boolean hasUnterminatedLine() { + return end == -1; + } + + /** + * Reads new input data into the buffer. Call only with pos == end or end == -1, + * depending on the desired outcome if the function throws. + */ + private void fillBuf() throws IOException { + int result = in.read(buf, 0, buf.length); + if (result == -1) { + throw new EOFException(); + } + pos = 0; + end = result; + } +} + diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/tts/AndroidTTSPlayer.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/tts/AndroidTTSPlayer.java new file mode 100644 index 0000000000..b8ac0c7c05 --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/tts/AndroidTTSPlayer.java @@ -0,0 +1,89 @@ +package com.mogo.utils.tts; + +import android.content.Context; +import android.media.AudioManager; +import android.speech.tts.TextToSpeech; +import android.speech.tts.UtteranceProgressListener; + +import com.mogo.utils.logger.Logger; + +import java.util.HashMap; +import java.util.Locale; + +/** + * @author congtaowang + * @since 2020-04-14 + *

+ * 描述 + */ +public class AndroidTTSPlayer extends UtteranceProgressListener implements TTSPlayer, TextToSpeech.OnInitListener { + + private static final String TAG = "AndroidTTSPlayer"; + + private TextToSpeech mTtsEngine; + private Context mContext; + private boolean mIsSuccess = false; + private HashMap< String, String > mParams; + + /** + * {@link TextToSpeech.Engine#KEY_PARAM_STREAM}, + * {@link TextToSpeech.Engine#KEY_PARAM_VOLUME}, + * {@link TextToSpeech.Engine#KEY_PARAM_PAN}. + * + * @param context + */ + public AndroidTTSPlayer( Context context ) { + mContext = context.getApplicationContext(); + mTtsEngine = new TextToSpeech( mContext, this ); + mParams = new HashMap<>(); + mParams.put( TextToSpeech.Engine.KEY_PARAM_STREAM, AudioManager.STREAM_ALARM + "" ); + mParams.put( TextToSpeech.Engine.KEY_PARAM_VOLUME, "1" ); + mParams.put( TextToSpeech.Engine.KEY_PARAM_PAN, "0" ); + } + + @Override + public void stop() { + if ( mTtsEngine != null ) { + mTtsEngine.stop(); + } + } + + @Override + public void speakTTS( String text ) { + if ( !mIsSuccess ) { + Logger.d( TAG, "do not support tts play." ); + return; + } + mParams.put( TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, text ); + mTtsEngine.speak( text, TextToSpeech.QUEUE_FLUSH, mParams ); + } + + @Override + public void onInit( int status ) { + if ( status == TextToSpeech.SUCCESS ) { + int result = mTtsEngine.setLanguage( Locale.CHINA ); + mTtsEngine.setPitch( 1.0f );// 设置音调,值越大声音越尖(女生),值越小则变成男声,1.0是常规 + mTtsEngine.setSpeechRate( 1.0f ); + mTtsEngine.setOnUtteranceProgressListener( this ); + if ( result != TextToSpeech.LANG_MISSING_DATA || result != TextToSpeech.LANG_NOT_SUPPORTED ) { + //系统支持中文播报 + mIsSuccess = true; + } + } + } + + @Override + public void onStart( String utteranceId ) { + + } + + @Override + public void onDone( String utteranceId ) { + + } + + @Override + public void onError( String utteranceId ) { + + } +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/tts/TTSPlayer.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/tts/TTSPlayer.java new file mode 100644 index 0000000000..b5cca2881e --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/tts/TTSPlayer.java @@ -0,0 +1,14 @@ +package com.mogo.utils.tts; + +/** + * @author congtaowang + * @since 2020-04-14 + *

+ * 描述 + */ +public interface TTSPlayer { + + void stop(); + + void speakTTS( String text ); +} diff --git a/foudations/mogo-utils/src/main/java/com/mogo/utils/tts/TTSPlayerFactory.java b/foudations/mogo-utils/src/main/java/com/mogo/utils/tts/TTSPlayerFactory.java new file mode 100644 index 0000000000..f37ca1721d --- /dev/null +++ b/foudations/mogo-utils/src/main/java/com/mogo/utils/tts/TTSPlayerFactory.java @@ -0,0 +1,16 @@ +package com.mogo.utils.tts; + +import android.content.Context; + +/** + * @author congtaowang + * @since 2020-04-14 + *

+ * 描述 + */ +public class TTSPlayerFactory { + + public static TTSPlayer getPlayer( Context context ) { + return new AndroidTTSPlayer( context ); + } +} diff --git a/gradle.properties b/gradle.properties index 199d16ede3..5f9477869a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,8 @@ # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m +#org.gradle.jvmargs=-Xmx1536m +org.gradle.jvmargs=-Xmx4096m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects @@ -17,4 +18,90 @@ org.gradle.jvmargs=-Xmx1536m android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true +org.gradle.parallel=true +## maven 配置 +RELEASE_REPOSITORY_URL=http://nexus.zhidaoauto.com/repository/maven-releases/ +SNAPSHOT_REPOSITORY_URL=http://nexus.zhidaoauto.com/repository/maven-snapshots/ +USERNAME=xintai +PASSWORD=xintai2018 +# 编译模式: false - 依赖本地版本, true - 依赖 maven 版本 +RELEASE=false +# 模块版本 +## 工程内模块 +MOGO_COMMONS_VERSION=1.2.1.22 +MOGO_UTILS_VERSION=1.2.1.22 +MAP_AMAP_VERSION=1.2.1.22 +MAP_AUTONAVI_VERSION=1.2.1.22 +MOGO_MAP_VERSION=1.2.1.22 +MOGO_MAP_API_VERSION=1.2.1.22 +MOGO_SERVICE_VERSION=1.2.1.22 +MOGO_SERVICE_API_VERSION=1.2.1.22 +MOGO_CONNECTION_VERSION=1.2.1.22 +MOGO_MODULE_APPS_VERSION=1.2.1.22 +MOGO_MODULE_NAVI_VERSION=1.2.1.22 +MOGO_MODULE_SHARE_VERSION=1.2.1.22 +MOGO_MODULE_COMMON_VERSION=1.2.1.22 +MOGO_MODULE_MAIN_VERSION=1.2.1.22 +MOGO_MODULE_MAP_VERSION=1.2.1.22 +MOGO_MODULE_SERVICE_VERSION=1.2.1.22 +MOGO_MODULE_EXTENSIONS_VERSION=1.2.1.22 +MOGO_MODULE_SEARCH_VERSION=1.2.1.22 +MOGO_MODULE_BACK_VERSION=1.2.1.22 +MOGO_MODULE_GPS_SIMULATOR_VERSION=1.2.1.22 +MOGO_MODULE_GPS_SIMULATOR_DEBUG_VERSION=1.2.1.22 +MOGO_MODULE_GPS_SIMULATOR_NOOP_VERSION=1.2.1.22 +MOGO_MODULE_AUTHORIZE_VERSION=1.2.1.22 +MOGO_MODULE_GUIDE_VERSION=1.2.1.22 +MOGO_MODULE_MEDIA_VERSION=1.2.1.22 +MOGO_MODULE_MAIN_LAUNCHER_VERSION = 1.2.1.22 +MOGO_MODULE_MAIN_INDEPENDENT_VERSION = 1.2.1.22 +MOGO_MODULE_V2X_VERSION=1.2.1.22 +# 基础服务实现:passport、socket、location +MOGO_BASE_SERVICES_APK_VERSION = 1.2.1.22 +MOGO_BASE_SERVICES_SDK_VERSION = 1.2.1.22 + +## 工程外部模块 +# 探路 +MOGO_MODULE_TANLU_VERSION=1.3.1.20 +# 车聊聊 +CARCHATTING_VERSION=1.4.8 +# 车聊聊接口 +CARCHATTINGPROVIDER_VERSION=1.3.4 +# 视频引导 +MOGO_MODULE_GUIDESHOW_VERSION=1.0.2-SNAPSHOT +# 视频引导接口 +MOGO_MODULE_GUIDESHOW_PROVIDER_VERSION=1.0.2-SNAPSHOT +# 在线车辆F +MOGO_MODULE_ONLINECAR_VERSION=1.0.3.2 +# 推送 +MOGO_MODULE_PUSH_VERSION=1.1.5.7 +MOGO_MODULE_PUSH_BASE_VERSION=1.1.5.5 +MOGO_MODULE_PUSH_NOOP_VERSION=1.1.5.6 +# 广告资源位 +MOGO_MODULE_AD_CARD_VERSION=1.0.1 +# 探路上报和分享模块 +TANLULIB_VERSION=1.3.1.20 +MOGO_MODULE_EVENT_PANEL_VERSION = 1.0.0-SNAPSHOT +MOGO_MODULE_EVENT_PANEL_NOOP_VERSION = 1.0.0-SNAPSHOT +#左侧面板模块 +MOGO_MODULE_LEFT_PANEL_VERSION = 1.2.1.10-SNAPSHOT +MOGO_MODULE_LEFT_PANEL_NOOP_VERSION = 1.2.1.10-SNAPSHOT + +# Boost分包 +BOOST_MULTIDEX_VERSION=1.0.0 +# hook ARouter分包实现 +HOOKPLUGIN_VERSION=1.0.0 + +# obu +MOGO_MODULE_OBU_VERSION = 1.2.1.10-SNAPSHOT + +# 闪屏页 +MOGO_MODULE_SPLASH_VERSION = 1.0.0-SNAPSHOT +MOGO_MODULE_SPLASH_NOOP_VERSION = 1.0.0-SNAPSHOT + +## 产品库必备配置 +applicationId=com.mogo.launcer +applicationName=IntelligentPilot +versionCode=80006 +versionName=8.0.6 \ No newline at end of file diff --git a/gradle/upload.gradle b/gradle/upload.gradle new file mode 100644 index 0000000000..a7ffd9f026 --- /dev/null +++ b/gradle/upload.gradle @@ -0,0 +1,68 @@ +apply plugin: 'maven' +apply plugin: 'maven-publish' + +task loggerSourcesJar(type: Jar) { + classifier = 'sources' + if (plugins.hasPlugin("java-library")) { + from sourceSets.main.java.srcDirs + } else if (plugins.hasPlugin("com.android.library")) { + from android.sourceSets.main.java.sourceFiles + } else if (plugins.hasPlugin('groovy')) { + from sourceSets.main.groovy.srcDirs + } +} + +artifacts { + archives loggerSourcesJar +} + +task loggerUpload(dependsOn: [uploadArchives, loggerSourcesJar]) { +} + +uploadArchives { + repositories { + mavenDeployer { + + println project.name + + String versionNameKey = "${project.name.replace("-", "_").toUpperCase()}_VERSION" + String versionName = getVersionNameValue(versionNameKey) + println versionName + + if (versionName == null || versionName.equals("")) { + project.logger.error("undefined versionName in root gradle.properties by ${versionNameKey}") + } + + pom.project { + packaging = 'aar' + groupId = GROUP + artifactId = POM_ARTIFACT_ID + version = versionName + } + + repository(url: rootProject.RELEASE_REPOSITORY_URL) { + authentication(userName: rootProject.USERNAME, password: rootProject.PASSWORD) + } + + snapshotRepository(url: rootProject.SNAPSHOT_REPOSITORY_URL) { + authentication(userName: rootProject.USERNAME, password: rootProject.PASSWORD) + } + } + } +} + +def getVersionNameValue(String key) { + File file = rootProject.file('gradle.properties') + String value = ""; + if (file.exists()) { + //加载资源 + InputStream inputStream = file.newDataInputStream(); + Properties properties = new Properties() + properties.load(inputStream) + + if (properties.containsKey(key)) { + value = properties.getProperty(key) + } + } + return value +} diff --git a/javadoc.gradle b/javadoc.gradle new file mode 100644 index 0000000000..839fea4005 --- /dev/null +++ b/javadoc.gradle @@ -0,0 +1,25 @@ +afterEvaluate { + rootProject.subprojects { project -> + println project.name + project.task("generateApiDoc", { + group "javadoc" + def rootProjectPath = rootProject.buildDir.absolutePath + def projectPath = new File("").absolutePath + def apiPackageFile = new File(projectPath, "apipackage.txt") + def sourcePath = new File(projectPath, "src/main/java") + def outputDocPath = new File(rootProjectPath, "javadoc/${project.name}") + doFirst { + println "javadoc -sourcepath ${sourcePath} -d ${outputDocPath} @${apiPackageFile}" + if (!apiPackageFile.exists()) { + throw new Exception("不是api模块") + } + } + doLast { + exec { + commandLine "javadoc", "-sourcepath", sourcePath, "-d", outputDocPath, "-encoding", "UTF-8", "@${apiPackageFile}" + } + } + }) + } +} + diff --git a/javadoc.sh b/javadoc.sh new file mode 100755 index 0000000000..b2b349fe7d --- /dev/null +++ b/javadoc.sh @@ -0,0 +1,4 @@ +#!/bin/sh + + + diff --git a/keystore/car_launcher.jks b/keystore/car_launcher.jks new file mode 100644 index 0000000000..10da6f41bd Binary files /dev/null and b/keystore/car_launcher.jks differ diff --git a/libraries/map-amap/.gitignore b/libraries/map-amap/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/libraries/map-amap/.gitignore @@ -0,0 +1 @@ +/build diff --git a/libraries/map-amap/build.gradle b/libraries/map-amap/build.gradle new file mode 100644 index 0000000000..780c7af6f6 --- /dev/null +++ b/libraries/map-amap/build.gradle @@ -0,0 +1,52 @@ +apply plugin: 'com.android.library' + +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") + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility 1.8 + targetCompatibility 1.8 + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation rootProject.ext.dependencies.androidxappcompat + api rootProject.ext.dependencies.amapnavi3dmap + api rootProject.ext.dependencies.amapsearch + api rootProject.ext.dependencies.amaplocation + + if (Boolean.valueOf(RELEASE)) { + implementation rootProject.ext.dependencies.mogoutils + implementation rootProject.ext.dependencies.mogomapapi + implementation rootProject.ext.dependencies.mogocommons + implementation rootProject.ext.dependencies.mogomapapi + } else { + implementation project(':foudations:mogo-utils') + implementation project(':libraries:mogo-map-api') + implementation project(':foudations:mogo-commons') + implementation project(':services:mogo-service-api') + + } +} + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() diff --git a/libraries/map-amap/consumer-rules.pro b/libraries/map-amap/consumer-rules.pro new file mode 100644 index 0000000000..11e9ffd54b --- /dev/null +++ b/libraries/map-amap/consumer-rules.pro @@ -0,0 +1,5 @@ +#-----library-MapAMap----- +-keep class com.mogo.map.impl.amap.hook.BnHooker.*{*;} +-keep class com.mogo.map.impl.amap.marker.CombineMovingPointOverlay.Status +-keep class com.mogo.map.impl.amap.navi.PathPlanningErrorCodeConstants +-keep class com.mogo.map.impl.amap.utils.MapStyleUtils.ColorEnum \ No newline at end of file diff --git a/libraries/map-amap/gradle.properties b/libraries/map-amap/gradle.properties new file mode 100644 index 0000000000..bc8dabb558 --- /dev/null +++ b/libraries/map-amap/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.map +POM_ARTIFACT_ID=map-amap +VERSION_CODE=1 \ No newline at end of file diff --git a/libraries/map-amap/proguard-rules.pro b/libraries/map-amap/proguard-rules.pro new file mode 100644 index 0000000000..7959227525 --- /dev/null +++ b/libraries/map-amap/proguard-rules.pro @@ -0,0 +1,27 @@ +# 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 + +#-----library-MapAMap----- +-keep class com.mogo.map.impl.amap.hook.BnHooker.*{*;} +-keep class com.mogo.map.impl.amap.marker.CombineMovingPointOverlay.Status +-keep class com.mogo.map.impl.amap.navi.PathPlanningErrorCodeConstants +-keep class com.mogo.map.impl.amap.utils.MapStyleUtils.ColorEnum \ No newline at end of file diff --git a/libraries/map-amap/src/main/AndroidManifest.xml b/libraries/map-amap/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..170516de73 --- /dev/null +++ b/libraries/map-amap/src/main/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapBaseMapView.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapBaseMapView.java new file mode 100644 index 0000000000..a318034ac3 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapBaseMapView.java @@ -0,0 +1,36 @@ +package com.mogo.map.impl.amap; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.annotation.Nullable; + +import com.amap.api.navi.AMapNaviView; +import com.mogo.map.IMogoMapView; +import com.mogo.map.MogoBaseMapView; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 描述 + */ +public class AMapBaseMapView extends MogoBaseMapView { + + public AMapBaseMapView( Context context ) { + super( context ); + } + + public AMapBaseMapView( Context context, @Nullable AttributeSet attrs ) { + super( context, attrs ); + } + + public AMapBaseMapView( Context context, @Nullable AttributeSet attrs, int defStyleAttr ) { + super( context, attrs, defStyleAttr ); + } + + @Override + protected IMogoMapView createMapView( Context context ) { + return new AMapNaviViewWrapper( new AMapNaviView( context ) ); + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapMarkerClickHandler.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapMarkerClickHandler.java new file mode 100644 index 0000000000..bdec4be752 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapMarkerClickHandler.java @@ -0,0 +1,32 @@ +package com.mogo.map.impl.amap; + +import com.amap.api.maps.model.Marker; +import com.mogo.map.marker.IMogoMarker; +import com.mogo.map.marker.IMogoMarkerClickListener; +import com.mogo.map.marker.MogoMarkersHandler; +import com.mogo.utils.logger.Logger; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * marker 点击事件处理 + */ +public class AMapMarkerClickHandler { + + public boolean handleMarkerClicked( Marker marker ) { + if ( marker == null ) { + return false; + } + if ( marker.getObject() instanceof IMogoMarker ) { + IMogoMarker mogoMarker = ( ( IMogoMarker ) marker.getObject() ); + final IMogoMarkerClickListener listener = mogoMarker.getOnMarkerClickListener(); + Logger.d( "AMapMarkerWrapper", "marker 点击回调:%s -> %s", mogoMarker, marker ); + if ( listener != null ) { + listener.onMarkerClicked( mogoMarker ); + } + return MogoMarkersHandler.getInstance().onMarkerClicked( mogoMarker ); + } + return false; + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapNaviViewWrapper.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapNaviViewWrapper.java new file mode 100644 index 0000000000..aef3a1b430 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapNaviViewWrapper.java @@ -0,0 +1,888 @@ +package com.mogo.map.impl.amap; + +import android.content.Context; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.Point; +import android.graphics.Rect; +import android.location.Location; +import android.os.Bundle; +import android.os.SystemClock; +import android.os.Trace; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.animation.Interpolator; + +import com.amap.api.maps.AMap; +import com.amap.api.maps.AMapUtils; +import com.amap.api.maps.CameraUpdateFactory; +import com.amap.api.maps.model.BitmapDescriptorFactory; +import com.amap.api.maps.model.CameraPosition; +import com.amap.api.maps.model.LatLng; +import com.amap.api.maps.model.LatLngBounds; +import com.amap.api.maps.model.Marker; +import com.amap.api.maps.model.MyLocationStyle; +import com.amap.api.maps.model.Poi; +import com.amap.api.maps.model.Polyline; +import com.amap.api.maps.model.animation.Animation; +import com.amap.api.maps.model.animation.TranslateAnimation; +import com.amap.api.navi.AMapNaviView; +import com.amap.api.navi.AMapNaviViewListener; +import com.amap.api.navi.AMapNaviViewOptions; +import com.amap.api.navi.enums.AMapNaviViewShowMode; +import com.amap.api.navi.model.NaviInfo; +import com.mogo.commons.debug.DebugConfig; +import com.mogo.map.IMogoMap; +import com.mogo.map.IMogoMapView; +import com.mogo.map.MogoLatLng; +import com.mogo.map.impl.amap.hook.BnHooker; +import com.mogo.map.impl.amap.marker.AMapMarkerWrapper; +import com.mogo.map.impl.amap.message.AMapMessageListener; +import com.mogo.map.impl.amap.message.AMapMessageManager; +import com.mogo.map.impl.amap.navi.NaviClient; +import com.mogo.map.impl.amap.utils.MogoMapUtils; +import com.mogo.map.impl.amap.utils.ObjectUtils; +import com.mogo.map.listener.MogoMapListenerHandler; +import com.mogo.map.marker.IMogoMarker; +import com.mogo.map.uicontroller.CarCursorOption; +import com.mogo.map.uicontroller.EnumMapUI; +import com.mogo.map.uicontroller.IMogoMapUIController; +import com.mogo.map.uicontroller.MapCameraPosition; +import com.mogo.map.uicontroller.MapControlResult; +import com.mogo.utils.WindowUtils; +import com.mogo.utils.logger.Logger; + +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-18 + *

+ * 代理高德导航地图 + */ +public class AMapNaviViewWrapper implements IMogoMapView, + IMogoMapUIController, + AMap.OnMarkerClickListener, + AMap.OnMapLoadedListener, + AMap.OnMapTouchListener, + AMap.OnPOIClickListener, + AMap.OnMapClickListener, + AMap.OnPolylineClickListener, + AMapNaviViewListener, + AMapMessageListener, + AMap.OnCameraChangeListener, + AMap.OnMyLocationChangeListener { + + private static final String TAG = "AMapNaviViewWrapper"; + + private final AMapNaviView mMapView; + private IMogoMap mIMap; + + private AMapMarkerClickHandler mMarkerClickHandler; + private EnumMapUI mCurrentUIMode; + + private boolean mIsCarLocked = false; + + private float mDefaultZoomLevel = 16.0f; + private final CarCursorOption DEFAULT_OPTION = new CarCursorOption.Builder() + .carCursorRes( R.drawable.map_api_ic_current_location2 ) + .naviCursorRes( R.drawable.ic_amap_navi_cursor ) + .build(); + private CarCursorOption mCarCursorOption = DEFAULT_OPTION; + + public AMapNaviViewWrapper( AMapNaviView mapView ) { + this.mMapView = mapView; + this.mIMap = new AMapWrapper( mMapView.getMap(), mMapView, this ); + try { + new BnHooker( mMapView.getMap(), mapView.getContext() ); + } catch ( Exception e ) { + e.printStackTrace(); + } + } + + private void initMapView() { + if ( mMapView == null ) { + return; + } + AMapNaviViewOptions options = mMapView.getViewOptions(); + if ( options != null ) { + // 设置是否开启自动黑夜模式切换,默认为false,不自动切换 + options.setAutoNaviViewNightMode( false ); + // 设置6秒后是否自动锁车 + options.setAutoLockCar( false ); + // 设置路线上的摄像头气泡是否显示 + options.setCameraBubbleShow( true ); + // 设置路线相关的配置属性,如:路线的路况颜色,路线上是否显示摄像头气泡等。 + // options.setRouteOverlayOptions( MapStyleUtils.getRouteOverlayOptions() ); + // 设置自车的图片对象 + options.setCarBitmap( BitmapFactory.decodeResource( getContext().getResources(), DEFAULT_OPTION.getNaviCursorRes() ) ); + // 设置指南针图标否在导航界面显示,默认显示。true,显示;false,隐藏。 + options.setCompassEnabled( false ); + // 黑夜模式 + options.setNaviNight( true ); + //设置路况光柱条是否显示(只适用于驾车导航,需要联网)。 + options.setTrafficBarEnabled( false ); + // 设置[实时交通图层开关按钮]是否显示(只适用于驾车导航,需要联网)。 + options.setTrafficLayerEnabled( false ); + // 设置导航界面是否显示路线全览按钮。 + options.setRouteListButtonShow( false ); + // 设置屏幕是否常亮,默认开启 + options.setScreenAlwaysBright( false ); + // 设置交通播报是否打开(只适用于驾车导航,需要联网)。 + options.setTrafficInfoUpdateEnabled( true ); + // 设置摄像头播报是否打开(只适用于驾车导航)。 + options.setCameraInfoUpdateEnabled( true ); + // 设置菜单按钮是否在导航界面显示。 + options.setSettingMenuEnabled( false ); + // 设置是否绘制显示交通路况的线路(彩虹线),拥堵-红色,畅通-绿色,缓慢-黄色,未知-蓝色。默认不绘制彩虹线。 + options.setTrafficLine( true ); + // 设置是否绘制牵引线(当前位置到目的地的指引线)。默认不绘制牵引线。 + options.setLeaderLineEnabled( -1 ); + // 设置导航界面UI是否显示。 + options.setLayoutVisible( false ); + // 设置是否自动画路 + options.setAutoDrawRoute( false ); + // 设置是否显示路口放大图(实景图) + options.setRealCrossDisplayShow( false ); + // 设置是否显示路口放大图(路口模型图) + options.setModeCrossDisplayShow( false ); + // 设置是否显示道路信息view + options.setLaneInfoShow( false ); + // 设置是否自动改变缩放等级 + options.setAutoChangeZoom( false ); + // 设置是否自动全览模式,即在算路成功后自动进入全览模式 + options.setAutoDisplayOverview( false ); + // 设置路线转向箭头隐藏和显示 + options.setNaviArrowVisible( false ); + // 通过路线是否自动置灰,仅支持驾车导航 + options.setAfterRouteAutoGray( true ); + options.setZoom( ( ( int ) mDefaultZoomLevel ) ); + options.setPointToCenter( 0.7D, 0.5D ); + // 2D模式 + options.setTilt( 0 ); + mMapView.setViewOptions( options ); + } + mMapView.setRouteOverlayVisible( false ); + mMapView.setCarOverlayVisible( false ); + setUIMode( EnumMapUI.CarUp_2D, null ); + } + + private void initListeners() { + + mMapView.setOnMarkerClickListener( this ); + mMarkerClickHandler = new AMapMarkerClickHandler(); + mMapView.setOnMapLoadedListener( this ); + mMapView.setOnMapTouchListener( this ); + mMapView.setOnPolylineClickListener( this ); + mMapView.setAMapNaviViewListener( this ); + mMapView.setOnCameraChangeListener( this ); + + final AMap aMap = mMapView.getMap(); + if ( aMap != null ) { + aMap.setOnPOIClickListener( this ); + aMap.setOnMapClickListener( this ); + aMap.setOnCameraChangeListener( this ); + aMap.setOnMyLocationChangeListener( this ); + } + AMapMessageManager.getInstance().registerAMapMessageListener( this ); + } + + private Context getContext() { + return mMapView.getContext(); + } + + @Override + public View getMapView() { + return mMapView; + } + + @Override + public IMogoMap getMap() { + return mIMap; + } + + @Override + public void onCreate( Bundle bundle ) { + if ( mMapView != null ) { + mMapView.onCreate( bundle ); + Logger.d( TAG, "map onCreate" ); + initMapView(); + initListeners(); + initMyLocation(); + } + } + + @Override + public void onResume() { + if ( mMapView != null ) { + mMapView.onResume(); + Logger.d( TAG, "map onResume" ); + } + } + + @Override + public void onPause() { + if ( mMapView != null ) { + mMapView.onPause(); + Logger.d( TAG, "map onPause" ); + } + } + + @Override + public void onDestroy() { + if ( mMapView != null ) { + mMapView.onDestroy(); + Logger.d( TAG, "map onDestroy" ); + } + } + + @Override + public void onSaveInstanceState( Bundle outState ) { + if ( mMapView != null ) { + mMapView.onSaveInstanceState( outState ); + Logger.d( TAG, "map onSaveInstanceState" ); + } + } + + @Override + public void onLowMemory() { + Logger.d( TAG, "map onLowMemory" ); + } + + /** + * 地图marker点击 + */ + @Override + public boolean onMarkerClick( Marker marker ) { + return mMarkerClickHandler.handleMarkerClicked( marker ); + } + + /** + * 地图加载完毕 + */ + @Override + public void onMapLoaded() { + MogoMapListenerHandler.getInstance().onMapLoaded(); + } + + /** + * 地图点击回调 + */ + @Override + public void onTouch( MotionEvent motionEvent ) { + MogoMapListenerHandler.getInstance().onTouch( motionEvent ); + } + + /** + * POI 点击 + */ + @Override + public void onPOIClick( Poi poi ) { + if ( InterceptorHandler.getInstance().ignorePoiClicked( getContext() ) ) { + return; + } + MogoMapListenerHandler.getInstance().onPOIClick( ObjectUtils.fromAMap( poi ) ); + } + + @Override + public void onMapClick( LatLng latLng ) { + if ( InterceptorHandler.getInstance().ignoreMapClicked( getContext() ) ) { + return; + } + MogoMapListenerHandler.getInstance().onMapClick( ObjectUtils.fromAMap( latLng ) ); + } + + @Override + public void onPolylineClick( Polyline polyline ) { + if ( !NaviClient.getInstance( getContext() ).isNaviing() ) { + NaviClient.getInstance( getContext() ).handleClickedPolyline( polyline ); + } + } + + @Override + public void onNaviSetting() { + + } + + @Override + public void onNaviCancel() { + + } + + @Override + public boolean onNaviBackClick() { + return true; + } + + /** + * @param mode 0:车头朝上状态;1:正北朝上模式 + */ + @Override + public void onNaviMapMode( int mode ) { + Logger.i( TAG, "mode=" + mode ); + MogoMapListenerHandler.getInstance().onMapModeChanged( mode == 0 ? EnumMapUI.CarUp_2D : EnumMapUI.NorthUP_2D ); + } + + @Override + public void onNaviTurnClick() { + + } + + @Override + public void onNextRoadClick() { + + } + + @Override + public void onScanViewButtonClick() { + + } + + @Override + public void onLockMap( boolean isLock ) { + Logger.d( TAG, "lock status = %s", isLock ); + mIsCarLocked = isLock; + Trace.beginSection( "timer.onCameraChangeFinish" ); + MogoMapListenerHandler.getInstance().onLockMap( isLock ); + Trace.endSection(); + } + + @Override + public void onNaviViewLoaded() { + + } + + @Override + public void onMapTypeChanged( int type ) { + if ( type == 4 ) { + MogoMapListenerHandler.getInstance().onMapModeChanged( EnumMapUI.Type_Light ); + } else if ( type == 3 ) { + MogoMapListenerHandler.getInstance().onMapModeChanged( EnumMapUI.Type_Night ); + } + } + + @Override + public void onNaviViewShowMode( int i ) { + + long delay = mMapView.getViewOptions().getLockMapDelayed(); + switch ( i ) { + case AMapNaviViewShowMode.SHOW_MODE_DEFAULT: + Logger.d( TAG, "普通模式" ); + break; + case AMapNaviViewShowMode.SHOW_MODE_DISPLAY_OVERVIEW: + Logger.d( TAG, "全览模式" ); + break; + case AMapNaviViewShowMode.SHOW_MODE_LOCK_CAR: + Logger.d( TAG, "锁车模式: %s", delay ); + break; + } + } + + @Override + public void setTrafficEnabled( boolean visible ) { + if ( checkAMapView() ) { + mMapView.setTrafficLine( visible ); + } + } + + @Override + public MapControlResult changeZoom( boolean zoom ) { + if ( checkAMapView() ) { + mDefaultZoomLevel = ( int ) ( getMap().getZoomLevel() + 0.5f ); + + if ( zoom ) { + if ( mDefaultZoomLevel >= 20 ) { + return MapControlResult.TARGET; + } + } else { + if ( mDefaultZoomLevel <= 3 ) { + return MapControlResult.TARGET; + } + } + + if ( zoom ) { + mDefaultZoomLevel += 2f; + if ( mDefaultZoomLevel > 20 ) { + mDefaultZoomLevel = 20; + } + } else { + mDefaultZoomLevel -= 2f; + if ( mDefaultZoomLevel < 1 ) { + mDefaultZoomLevel = 1; + } + } + changeZoom( ( int ) mDefaultZoomLevel ); + } + return MapControlResult.SUCCESS; + } + + @Override + public MapControlResult changeZoom( float zoom ) { + Logger.d( TAG, "changeZoom %s", zoom ); + if ( DebugConfig.isDebug() ) { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + } + getMap().changeZoom( zoom ); + return MapControlResult.SUCCESS; + } + + @Override + public void changeMapMode( EnumMapUI ui ) { + if ( ui == null ) { + return; + } + if ( checkAMapView() ) { + AMapNaviViewOptions options = mMapView.getViewOptions(); + if ( options == null ) { + options = new AMapNaviViewOptions(); + } + switch ( ui ) { + case CarUp_2D: + case CarUp_3D: + case NorthUP_2D: + setUIMode( ui, options ); + break; + case Type_Light: + options.setNaviNight( false ); + break; + case Type_Night: + options.setNaviNight( true ); + break; + case Type_AUTO_LIGHT_Night: + options.setNaviNight( false ); + options.setAutoNaviViewNightMode( true ); + break; + } + mMapView.setViewOptions( options ); + } + } + + private void setUIMode( EnumMapUI ui, AMapNaviViewOptions options ) { + this.mCurrentUIMode = ui; + switch ( ui ) { + case CarUp_2D: + case CarUp_3D: + mMapView.setNaviMode( AMapNaviView.CAR_UP_MODE ); + break; + case NorthUP_2D: + mMapView.setNaviMode( AMapNaviView.NORTH_UP_MODE ); + break; + } + + Logger.d( TAG, "mCurrentUIMode--->" + mCurrentUIMode.name() ); + if ( options == null ) { + return; + } + switch ( ui ) { + case CarUp_2D: + case NorthUP_2D: + options.setTilt( 0 ); + break; + case CarUp_3D: + options.setTilt( 60 ); + break; + } + } + + private boolean checkAMapView() { + if ( mMapView == null ) { + Logger.e( TAG, "高德mapView实例为空,请检查" ); + return false; + } + return true; + } + + @Override + public void moveToCenter( MogoLatLng latLng, boolean animate ) { + Logger.d( TAG, "move to center %s", latLng ); + if ( latLng == null || latLng.lat == 0.0d || latLng.lng == 0.0d ) { + Logger.e( TAG, "latlng = null or is illegal" ); + return; + } + if ( DebugConfig.isDebug() ) { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + } + loseLockMode(); + if ( animate ) { + mMapView.getMap().animateCamera( CameraUpdateFactory.newLatLng( new LatLng( latLng.lat, latLng.lng ) ) ); + } else { + mMapView.getMap().moveCamera( CameraUpdateFactory.newLatLng( new LatLng( latLng.lat, latLng.lng ) ) ); + } + } + + @Override + public void showMyLocation( boolean visible ) { + Logger.d( TAG, "showMyLocation1 %s", visible ); + if ( visible && NaviClient.getInstance( getContext() ).isNaviing() ) { + return; + } + if ( DebugConfig.isDebug() ) { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + } + if ( checkAMapView() ) { + MyLocationStyle style = mMapView.getMap().getMyLocationStyle(); + style.showMyLocation( visible ); + if ( visible ) { + // 强制刷新一遍车标 + style.myLocationIcon( BitmapDescriptorFactory.fromResource( mCarCursorOption.getCarCursorRes() ) ); + } + mMapView.getMap().setMyLocationStyle( style ); + } + } + + @Override + public void showMyLocation( View view ) { + if ( NaviClient.getInstance( getContext() ).isNaviing() ) { + return; + } + if ( DebugConfig.isDebug() ) { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + } + if ( checkAMapView() ) { + MyLocationStyle style = mMapView.getMap().getMyLocationStyle(); + style.showMyLocation( true ); + style.myLocationIcon( BitmapDescriptorFactory.fromView( view ) ); + mMapView.getMap().setMyLocationStyle( style ); + } + } + + public void initMyLocation() { + if ( checkAMapView() ) { + mMapView.getMap().setMyLocationEnabled( true ); + MyLocationStyle style = mMapView.getMap().getMyLocationStyle(); + style.myLocationType( MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER ); + style.interval( 1000 ); + style.anchor( 0.5F, 0.5F ); + style.strokeColor( Color.TRANSPARENT ); + style.strokeWidth( 0 ); + style.radiusFillColor( Color.TRANSPARENT ); + mMapView.getMap().setMyLocationStyle( style ); + } + } + + @Override + public void recoverLockMode() { + if ( checkAMapView() ) { + if ( DebugConfig.isDebug() ) { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + } + Logger.d( TAG, "锁车" ); + mMapView.recoverLockMode(); + mIsCarLocked = true; + } + } + + @Override + public void loseLockMode() { + if ( DebugConfig.isDebug() ) { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + } + Logger.d( TAG, "解锁锁车" ); + mockTouchEvent(); + mIsCarLocked = false; + } + + /** + * 模拟点击事件,达到锁车->普通事件 + */ + private void mockTouchEvent() { + long downTime = SystemClock.uptimeMillis(); + long eventTime = downTime + 1; + int metaState = 0; + MotionEvent motionEvent = MotionEvent.obtain( downTime, eventTime, MotionEvent.ACTION_DOWN, 0, 0, metaState ); + mMapView.dispatchTouchEvent( motionEvent ); + MotionEvent upEvent = MotionEvent.obtain( downTime + 1, eventTime + 2, MotionEvent.ACTION_UP, 0, 0, metaState ); + mMapView.dispatchTouchEvent( upEvent ); + } + + @Override + public void setLockZoom( int var1 ) { + if ( checkAMapView() ) { + if ( DebugConfig.isDebug() ) { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + } + Logger.d( TAG, "Zoom锁定锁车比例尺 %s", var1 ); + mMapView.setLockZoom( var1 ); + } + } + + @Override + public void displayOverview( Rect bounds ) { + if ( checkAMapView() ) { + if ( NaviClient.getInstance( getContext() ).isNaviing() ) { + loseLockMode(); + NaviClient.getInstance( getContext() ).displayOverview( bounds ); + } + } + } + + @Override + public float getScalePerPixel() { + return getMap().getScalePerPixel(); + } + + @Override + public float getZoomLevel() { + return getMap().getZoomLevel(); + } + + @Override + public void onNaviStarted() { + if ( checkAMapView() ) { + mMapView.setCarOverlayVisible( true ); + showMyLocation( false ); + } + } + + @Override + public void onNaviStopped() { + if ( checkAMapView() ) { + mMapView.setCarOverlayVisible( false ); + showMyLocation( true ); + NaviClient.getInstance( getContext() ).startAimlessMode(); + } + } + + @Override + public void onNaviInfoUpdat( NaviInfo naviInfo ) { + + } + + @Override + public void onCalculateSuccess() { + loseLockMode(); + } + + @Override + public void onCameraChange( CameraPosition cameraPosition ) { + } + + @Override + public void onCameraChangeFinish( CameraPosition cameraPosition ) { + if ( cameraPosition != null ) { + Trace.beginSection( "timer.onCameraChangeFinish" ); + MogoMapListenerHandler.getInstance().onMapChanged( ObjectUtils.fromAMap( cameraPosition.target ), + cameraPosition.zoom, + cameraPosition.tilt, + cameraPosition.bearing ); + Trace.endSection(); + } + } + + @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; + } + + @Override + public MogoLatLng getWindowCenterLocation() { + try { + return ObjectUtils.fromAMap( mMapView.getMap().getCameraPosition().target ); + } catch ( Exception e ) { + + } + return null; + } + + @Override + public void setPointToCenter( double mapCenterX, double mapCenterY ) { + if ( checkAMapView() ) { + if ( DebugConfig.isDebug() ) { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + } + Logger.d( TAG, "setPointToCenter(%s, %s)", mapCenterX, mapCenterY ); + AMapNaviViewOptions options = mMapView.getViewOptions(); + options.setPointToCenter( mapCenterX, mapCenterY ); + mMapView.setViewOptions( options ); + } + } + + @Override + public Point getLocationPointInScreen( MogoLatLng latLng ) { + if ( checkAMapView() ) { + try { + return mMapView.getMap() + .getProjection() + .toScreenLocation( ObjectUtils.fromMogo2( latLng ) ); + } catch ( Exception e ) { + return null; + } + } + return null; + } + + @Override + public MogoLatLng getLocationMogoLatLngInScreen( Point point ) { + if ( checkAMapView() ) { + try { + return ObjectUtils.fromAMap( + mMapView.getMap().getProjection().fromScreenLocation( point ) ); + } catch ( Exception e ) { + return null; + } + } + return null; + } + + @Override + public void startJumpAnimation( IMogoMarker marker, float high, Interpolator interpolator, + long duration ) { + if ( marker == null || high <= 0.0f || interpolator == null || duration < 0 ) { + return; + } + try { + final LatLng latLng = ObjectUtils.fromMogo2( marker.getPosition() ); + Point point = mMapView.getMap().getProjection().toScreenLocation( latLng ); + point.y -= WindowUtils.dip2px( getContext(), high ); + LatLng target = mMapView.getMap().getProjection().fromScreenLocation( point ); + //使用TranslateAnimation,填写一个需要移动的目标点 + Animation animation = new TranslateAnimation( target ); + animation.setInterpolator( interpolator ); + //整个移动所需要的时间 + animation.setDuration( duration ); + //设置动画 + if ( marker instanceof AMapMarkerWrapper ) { + ( ( AMapMarkerWrapper ) marker ).getMarker().setAnimation( animation ); + ( ( AMapMarkerWrapper ) marker ).getMarker().startAnimation(); + } + } catch ( Exception e ) { + Logger.e( TAG, e, "error." ); + } + } + + @Override + public void setRenderFps( int fps ) { + if ( checkAMapView() ) { + if ( mMapView.getMap() != null ) { + mMapView.getMap().setRenderFps( fps ); + Logger.d( TAG, "设置刷新帧率 fps = %s", fps ); + } + } + } + + @Override + public void showBounds( String tag, MogoLatLng carPosition, List< MogoLatLng > lonLats, Rect bound, boolean lockCarPosition ) { + if ( !checkAMapView() ) { + return; + } + try { + if ( DebugConfig.isDebug() ) { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + } + LatLngBounds latLngBounds = MogoMapUtils.getLatLngBounds( carPosition, lonLats, lockCarPosition ); + if ( !lockCarPosition ) { + loseLockMode(); + } + mMapView.getMap().moveCamera( CameraUpdateFactory.newLatLngBoundsRect( latLngBounds, bound.left, bound.right, bound.top, bound.bottom ) ); + } catch ( Exception e ) { + Logger.e( TAG, e, "%s error.", tag ); + } + } + + @Override + public void forceRender() { + if ( checkAMapView() ) { + mMapView.getMap().runOnDrawFrame(); + } + } + + @Override + public float calculateLineDistance( MogoLatLng p1, MogoLatLng p2 ) throws Exception { + if ( p1 == null || p2 == null ) { + throw new Exception( "计算距离的点不能为 null" ); + } + return AMapUtils.calculateLineDistance( ObjectUtils.fromMogo2( p1 ), ObjectUtils.fromMogo2( p2 ) ); + } + + @Override + public void onMyLocationChange( Location location ) { + NaviClient.getInstance( getContext() ).syncCarLocation( location ); + } + + @Override + public EnumMapUI getCurrentUiMode() { + return mCurrentUIMode; + } + + @Override + public void changeMyLocation( Location location ) { + } + + @Override + public synchronized boolean isCarLocked() { + return mIsCarLocked; + } + + @Override + public void setCarCursorOption( CarCursorOption option ) { + if ( mCarCursorOption != null && mCarCursorOption != DEFAULT_OPTION ) { + mCarCursorOption.destroy(); + } + if ( option != null ) { + try { + mCarCursorOption = option.clone(); + } catch ( Exception e ) { + mCarCursorOption = DEFAULT_OPTION; + } + } else { + mCarCursorOption = DEFAULT_OPTION; + } + if ( !checkAMapView() ) { + return; + } + AMapNaviViewOptions options = mMapView.getViewOptions(); + if ( options != null && mCarCursorOption.getNaviCursorRes() != 0 ) { + options.setCarBitmap( BitmapFactory.decodeResource( getContext().getResources(), mCarCursorOption.getNaviCursorRes() ) ); + } else { + options.setCarBitmap( BitmapFactory.decodeResource( getContext().getResources(), DEFAULT_OPTION.getNaviCursorRes() ) ); + } + mMapView.setViewOptions( options ); + + if ( mMapView.getMap() == null ) { + return; + } + MyLocationStyle style = mMapView.getMap().getMyLocationStyle(); + if ( mCarCursorOption.getCarCursorBmp() != null && !mCarCursorOption.getCarCursorBmp().isRecycled() ) { + style.myLocationIcon( BitmapDescriptorFactory.fromBitmap( mCarCursorOption.getCarCursorBmp() ) ); + } else { + if ( mCarCursorOption.getCarCursorRes() != 0 ) { + style.myLocationIcon( BitmapDescriptorFactory.fromResource( mCarCursorOption.getCarCursorRes() ) ); + } else { + style.myLocationIcon( BitmapDescriptorFactory.fromResource( DEFAULT_OPTION.getCarCursorRes() ) ); + } + } + mMapView.getMap().setMyLocationStyle( style ); + } + + @Override + public MapCameraPosition getMapCameraPosition() { + if ( checkAMapView() ) { + CameraPosition cameraPosition = mMapView.getMap().getCameraPosition(); + return ObjectUtils.fromAMap( cameraPosition ); + } + return null; + } + + @Override + public void changeBearing( float bearing ) { + if ( checkAMapView() ) { + mMapView.getMap().moveCamera( CameraUpdateFactory.changeBearing( bearing ) ); + } + } +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/amap/AMapUiSettingsWrapper.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapUiSettingsWrapper.java similarity index 93% rename from libraries/mogo-map/src/main/java/com/mogo/map/amap/AMapUiSettingsWrapper.java rename to libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapUiSettingsWrapper.java index ff966d000e..fa904a0afa 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/amap/AMapUiSettingsWrapper.java +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapUiSettingsWrapper.java @@ -1,7 +1,7 @@ -package com.mogo.map.amap; +package com.mogo.map.impl.amap; import com.amap.api.maps.UiSettings; -import com.mogo.map.IUiSettings; +import com.mogo.map.IMogoUiSettings; import java.lang.reflect.Method; @@ -11,7 +11,7 @@ import java.lang.reflect.Method; *

* 代理高德地图UiSettings */ -public class AMapUiSettingsWrapper implements IUiSettings { +public class AMapUiSettingsWrapper implements IMogoUiSettings { private UiSettings mUiSettings; @@ -93,7 +93,7 @@ public class AMapUiSettingsWrapper implements IUiSettings { public void setLogoEnable( boolean enabled ) { if ( mUiSettings != null ) { try { - Method method = mUiSettings.getClass().getMethod( "setLogoEnable", Boolean.class ); + Method method = mUiSettings.getClass().getMethod( "setLogoEnable", boolean.class ); method.setAccessible( true ); method.invoke( mUiSettings, enabled ); } catch ( Exception e ) { diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapWrapper.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapWrapper.java new file mode 100644 index 0000000000..c796d9134a --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/AMapWrapper.java @@ -0,0 +1,255 @@ +package com.mogo.map.impl.amap; + +import android.content.Context; + +import com.amap.api.maps.AMap; +import com.amap.api.maps.CameraUpdateFactory; +import com.amap.api.maps.LocationSource; +import com.amap.api.maps.model.Marker; +import com.amap.api.maps.model.MarkerOptions; +import com.amap.api.maps.model.Polyline; +import com.amap.api.maps.model.PolylineOptions; +import com.amap.api.navi.AMapNaviView; +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.navi.NaviClient; +import com.mogo.map.impl.amap.overlay.AMapPolylineWrapper; +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; +import com.mogo.map.marker.MogoMarkersHandler; +import com.mogo.map.overlay.IMogoPolyline; +import com.mogo.map.overlay.MogoPolylineOptions; +import com.mogo.map.uicontroller.IMogoMapUIController; +import com.mogo.utils.logger.Logger; + +import java.util.ArrayList; + +/** + * @author congtaowang + * @since 2019-12-18 + *

+ * 代理高德AMap + */ +public class AMapWrapper implements IMogoMap { + + private static final String TAG = "AMapWrapper"; + + private static AMap sAMap; + private IMogoMapUIController mUIcontroller; + private AMap mAMap; + private AMapNaviView mMapView; + private IMogoUiSettings mUiSettings; + + public AMapWrapper( AMap map, AMapNaviView mapView, IMogoMapUIController controller ) { + this.mAMap = map; + sAMap = map; + this.mMapView = mapView; + mUIcontroller = controller; + // 设置实现自定义 info window + mAMap.setInfoWindowAdapter( new AMapInfoWindowAdapter() ); + AMapUIController.getInstance().initClient( mUIcontroller ); + } + + public static AMap getAMap() { + return sAMap; + } + + @Override + public IMogoUiSettings getUiSettings() { + if ( !checkAMap() ) { + return null; + } + if ( mUiSettings == null ) { + mUiSettings = new AMapUiSettingsWrapper( mAMap.getUiSettings() ); + } + return mUiSettings; + } + + @Override + public IMogoMapUIController getUIController() { + return mUIcontroller; + } + + @Override + public IMogoMarker addMarker( String tag, MogoMarkerOptions options ) { + if ( !checkAMap() ) { + return null; + } + MarkerOptions markerOptions = ObjectUtils.fromMogo( options ); + if ( markerOptions == null ) { + Logger.e( TAG, "marker参数为空" ); + return null; + } + final IMogoMarker mogoMarker = new AMapMarkerWrapper( mAMap.addMarker( markerOptions ), options ); + if ( options.isAutoManager() ) { + MogoMarkersHandler.getInstance().add( tag, mogoMarker ); + } + return mogoMarker; + } + + @Override + public ArrayList< IMogoMarker > addMarkers( String tag, ArrayList< MogoMarkerOptions > options, boolean moveToCenter ) { + if ( !checkAMap() ) { + return null; + } + + if ( options == null || options.isEmpty() ) { + return null; + } + + // 地图导航时,忽略参数 + if ( InterceptorHandler.getInstance().ignoreAddMarkersMoveToCenterParameters( getContext() ) ) { + moveToCenter = false; + } + + ArrayList< Marker > markers = null; + ArrayList< MarkerOptions > markerOptions = new ArrayList<>(); + ArrayList< IMogoMarker > mogoMarkers = new ArrayList<>(); + + for ( MogoMarkerOptions option : options ) { + if ( option == null ) { + continue; + } + MarkerOptions mo = ObjectUtils.fromMogo( option ); + if ( mo == null ) { + continue; + } + markerOptions.add( mo ); + } + if ( markerOptions.isEmpty() ) { + return null; + } + markers = mAMap.addMarkers( markerOptions, moveToCenter ); + if ( markers == null || markers.isEmpty() ) { + return null; + } + for ( int i = 0; i < markers.size(); i++ ) { + Marker marker = markers.get( i ); + if ( marker == null ) { + continue; + } + mogoMarkers.add( new AMapMarkerWrapper( marker, options.get( i ) ) ); + } + MogoMarkersHandler.getInstance().add( tag, mogoMarkers ); + return mogoMarkers; + } + + @Override + public void clear() { + if ( checkAMap() ) { + mAMap.clear(); + } + } + + @Override + public void clear( boolean isKeepMyLocationOverlay ) { + if ( checkAMap() ) { + mAMap.clear( isKeepMyLocationOverlay ); + } + } + + @Override + public void setPointToCenter( int x, int y ) { + if ( checkAMap() ) { + mAMap.setPointToCenter( x, y ); + } + } + + @Override + public void setTouchPoiEnable( boolean touchPoiEnable ) { + if ( checkAMap() ) { + mAMap.setTouchPoiEnable( touchPoiEnable ); + } + } + + @Override + public void setTrafficEnable( boolean enable ) { + if ( checkAMap() ) { + mAMap.setTrafficEnabled( enable ); + } + } + + @Override + public void showBuildings( boolean enabled ) { + if ( checkAMap() ) { + mAMap.showBuildings( enabled ); + } + } + + @Override + public void showIndoorMap( boolean enable ) { + if ( checkAMap() ) { + mAMap.showIndoorMap( enable ); + } + } + + @Override + public void showMapText( boolean enable ) { + if ( checkAMap() ) { + mAMap.showMapText( enable ); + } + } + + @Override + public void stopAnimation() { + if ( checkAMap() ) { + mAMap.stopAnimation(); + } + } + + @Override + public float getScalePerPixel() { + if ( checkAMap() ) { + return mAMap.getScalePerPixel(); + } + return 0; + } + + @Override + public void changeZoom( float zoom ) { + if ( checkAMap() ) { + mAMap.moveCamera( CameraUpdateFactory.zoomTo( zoom ) ); + } + } + + @Override + public float getZoomLevel() { + if ( checkAMap() ) { + try { + return mAMap.getCameraPosition().zoom; + } catch ( Exception e ) { + + } + } + return 0; + } + + @Override + public IMogoPolyline addPolyline( MogoPolylineOptions options ) { + if ( checkAMap() ) { + PolylineOptions polylineOptions = ObjectUtils.fromMogo( options ); + if ( polylineOptions == null ) { + return null; + } + Polyline polyline = mAMap.addPolyline( polylineOptions ); + return new AMapPolylineWrapper( polyline, options ); + } + return null; + } + + private boolean checkAMap() { + if ( mAMap == null ) { + Logger.e( TAG, "高德map实例为空,请检查" ); + return false; + } + return true; + } + + private Context getContext() { + return mMapView.getContext(); + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/IInterceptor.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/IInterceptor.java new file mode 100644 index 0000000000..a52ef55c39 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/IInterceptor.java @@ -0,0 +1,45 @@ +package com.mogo.map.impl.amap; + +import android.content.Context; + +/** + * @author congtaowang + * @since 2019-12-27 + *

+ * 操作拦截器 + */ +public interface IInterceptor { + + /** + * 是否忽略添加多个marker时聚拢参数 + *

+ * 导航时:不需要聚拢 + * + * @return true - 忽略 false - 不忽略 + */ + boolean ignoreAddMarkersMoveToCenterParameters( Context context ); + + /** + * 导航时,是否响应 poi 点击 + * + * @param context + * @return + */ + boolean ignorePoiClicked( Context context ); + + /** + * 导航时,是否响应地图点击 + * + * @param context + * @return + */ + boolean ignoreMapClicked( Context context ); + + /** + * 请求绘制路线 + * + * @param context + * @return + */ + boolean ignoreDrawRouteOverlay( Context context ); +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/InterceptorHandler.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/InterceptorHandler.java new file mode 100644 index 0000000000..7ed3e125aa --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/InterceptorHandler.java @@ -0,0 +1,60 @@ +package com.mogo.map.impl.amap; + +import android.content.Context; + +import com.mogo.map.impl.amap.navi.NaviClient; + +/** + * @author congtaowang + * @since 2019-12-27 + *

+ * 操作拦截器 + */ +public class InterceptorHandler implements IInterceptor { + + private static volatile InterceptorHandler sInstance; + + private Context mContext; + + private InterceptorHandler() { + } + + public static InterceptorHandler getInstance() { + if ( sInstance == null ) { + synchronized ( InterceptorHandler.class ) { + if ( sInstance == null ) { + sInstance = new InterceptorHandler(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + public void init( Context context ) { + mContext = context; + } + + @Override + public boolean ignoreAddMarkersMoveToCenterParameters( Context context ) { + return NaviClient.getInstance( context ).isNaviing(); + } + + @Override + public boolean ignorePoiClicked( Context context ) { + return NaviClient.getInstance( context ).isNaviing(); + } + + @Override + public boolean ignoreMapClicked( Context context ) { + return NaviClient.getInstance( context ).isNaviing(); + } + + @Override + public boolean ignoreDrawRouteOverlay( Context context ) { + return NaviClient.getInstance( context ).isNaviing(); + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/hook/BnHooker.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/hook/BnHooker.java new file mode 100644 index 0000000000..0840157652 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/hook/BnHooker.java @@ -0,0 +1,60 @@ +package com.mogo.map.impl.amap.hook; + +import android.content.Context; + +import com.amap.api.maps.AMap; +import com.autonavi.amap.mapcore.interfaces.IAMap; +import com.autonavi.base.amap.api.mapcore.IAMapDelegate; +import com.autonavi.base.amap.mapcore.interfaces.IAMapListener; +import com.mogo.map.impl.amap.navi.NaviClient; +import com.mogo.utils.logger.Logger; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * @author congtaowang + * @since 2020-03-12 + *

+ * 描述 + */ +public class BnHooker implements InvocationHandler { + + private static final String TAG = "BnHooker"; + private final Context mContext; + + private Object host; + + public BnHooker( AMap map, Context context ) throws Exception { + + mContext = context; + + if ( map == null ) { + return; + } + Field field = AMap.class.getDeclaredField( "a" ); + field.setAccessible( true ); + host = field.get( map ); + Object object = Proxy.newProxyInstance( + BnHooker.class.getClassLoader(), + new Class[]{ + com.amap.api.col.n3.ft.a.class, + IAMapDelegate.class, + IAMapListener.class, + IAMap.class + }, + this + ); + field.set( map, object ); + } + + @Override + public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable { + if ( method.getName().equals( "setRenderFps" ) ) { + return method.invoke( host, 10 ); + } + return method.invoke( host, args ); + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/location/ALocationClient.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/location/ALocationClient.java new file mode 100644 index 0000000000..a551c302bc --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/location/ALocationClient.java @@ -0,0 +1,158 @@ +package com.mogo.map.impl.amap.location; + +import android.content.Context; +import android.os.Trace; + +import com.amap.api.location.AMapLocation; +import com.amap.api.location.AMapLocationClient; +import com.amap.api.location.AMapLocationClientOption; +import com.amap.api.location.AMapLocationListener; +import com.mogo.map.impl.amap.utils.ObjectUtils; +import com.mogo.map.location.IMogoLocationClient; +import com.mogo.map.location.IMogoLocationListener; +import com.mogo.map.location.MogoLocation; +import com.mogo.utils.logger.Logger; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * @author congtaowang + * @since 2019-12-19 + *

+ * 高德定位 + */ +public class ALocationClient implements IMogoLocationClient { + + private static final String TAG = "LocationClient"; + + private Set< IMogoLocationListener > sListeners = new HashSet<>( 10 ); + private MogoLocation mLastLocation; + private AMapLocationListener mListener = new InternalLocationListener(); + + private boolean mIsDestroyed = false; + + public ALocationClient( Context context ) { + mClient = new AMapLocationClient( context ); + mClient.setLocationListener( mListener ); + mLastLocation = ObjectUtils.fromAMap( mClient.getLastKnownLocation() ); + if ( mLastLocation == null ) { + mLastLocation = new MogoLocation(); + } + } + + private AMapLocationClient mClient; + + @Override + public void start() { + start( 2_000L ); + } + + @Override + public void start( long interval ) { + if ( mIsDestroyed ) { + destroyWarming(); + return; + } + if ( mClient != null ) { + AMapLocationClientOption option = new AMapLocationClientOption(); + option.setLocationMode( AMapLocationClientOption.AMapLocationMode.Hight_Accuracy ); + option.setNeedAddress( true ); + option.setGpsFirst( true ); + option.setInterval( interval ); + mClient.setLocationOption( option ); + mClient.startLocation(); + } + } + + @Override + public void stop() { + if ( mIsDestroyed ) { + destroyWarming(); + return; + } + if ( mClient != null && mClient.isStarted() ) { + mClient.stopLocation(); + } + } + + @Override + public void addLocationListener( IMogoLocationListener listener ) { + if ( mIsDestroyed ) { + destroyWarming(); + return; + } + if ( listener != null ) { + synchronized ( sListeners ) { + sListeners.add( listener ); + } + } + } + + @Override + public void removeLocationListener( IMogoLocationListener listener ) { + if ( mIsDestroyed ) { + destroyWarming(); + return; + } + if ( listener != null ) { + synchronized ( sListeners ) { + sListeners.remove( listener ); + } + } + } + + @Override + public MogoLocation getLastKnowLocation() { + if ( mIsDestroyed ) { + destroyWarming(); + return null; + } + return mLastLocation; + } + + @Override + public synchronized void destroy() { + mIsDestroyed = true; + if ( sListeners != null ) { + sListeners.clear(); + } + sListeners = null; + if ( mClient != null ) { + mClient.unRegisterLocationListener( mListener ); + mClient.stopLocation(); + mClient.onDestroy(); + } + mClient = null; + mLastLocation = null; + } + + private class InternalLocationListener implements AMapLocationListener { + @Override + public void onLocationChanged( AMapLocation aMapLocation ) { + if ( mIsDestroyed ) { + destroyWarming(); + return; + } + if ( aMapLocation == null || + aMapLocation.getLatitude() == 0.0D || + aMapLocation.getLongitude() == 0.0D ) { + return; + } + Trace.beginSection("timer.onLocationChanged"); + mLastLocation = ObjectUtils.fromAMap( aMapLocation ); + synchronized ( sListeners ) { + Iterator< IMogoLocationListener > listenerIterator = sListeners.iterator(); + while ( listenerIterator.hasNext() ) { + listenerIterator.next().onLocationChanged( mLastLocation.clone() ); + } + } + Trace.endSection(); + } + } + + private void destroyWarming() { + Logger.w( TAG, "location client has destroyed." ); + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/marker/AMapInfoWindowAdapter.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/marker/AMapInfoWindowAdapter.java new file mode 100644 index 0000000000..fa7a13eae3 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/marker/AMapInfoWindowAdapter.java @@ -0,0 +1,35 @@ +package com.mogo.map.impl.amap.marker; + +import android.view.View; + +import com.amap.api.maps.AMap; +import com.amap.api.maps.model.Marker; +import com.mogo.map.marker.IMogoInfoWindowAdapter; +import com.mogo.map.marker.IMogoMarker; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * 自定义infowindow + */ +public final class AMapInfoWindowAdapter implements AMap.InfoWindowAdapter { + + @Override + public View getInfoWindow( Marker marker ) { + if ( marker.getObject() instanceof IMogoMarker ) { + IMogoMarker mogoMarker = ( ( IMogoMarker ) marker.getObject() ); + IMogoInfoWindowAdapter delegate = mogoMarker.getInfoWindowAdapter(); + if ( delegate != null ) { + return delegate.getInfoWindow( mogoMarker ); + } + } + + return null; + } + + @Override + public View getInfoContents( Marker marker ) { + return null; + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/marker/AMapMarkerWrapper.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/marker/AMapMarkerWrapper.java new file mode 100644 index 0000000000..8935812bcd --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/marker/AMapMarkerWrapper.java @@ -0,0 +1,513 @@ +package com.mogo.map.impl.amap.marker; + +import android.graphics.Bitmap; +import android.graphics.Point; +import android.view.View; +import android.view.animation.Interpolator; + +import com.amap.api.maps.model.BitmapDescriptor; +import com.amap.api.maps.model.BitmapDescriptorFactory; +import com.amap.api.maps.model.LatLng; +import com.amap.api.maps.model.Marker; +import com.amap.api.maps.model.MarkerOptions; +import com.amap.api.maps.model.animation.AlphaAnimation; +import com.amap.api.maps.model.animation.Animation; +import com.amap.api.maps.model.animation.AnimationSet; +import com.amap.api.maps.model.animation.ScaleAnimation; +import com.amap.api.maps.model.animation.TranslateAnimation; +import com.amap.api.maps.utils.overlay.MovingPointOverlay; +import com.mogo.commons.AbsMogoApplication; +import com.mogo.map.MogoLatLng; +import com.mogo.map.impl.amap.AMapWrapper; +import com.mogo.map.impl.amap.utils.ObjectUtils; +import com.mogo.map.marker.IMogoInfoWindowAdapter; +import com.mogo.map.marker.IMogoMarker; +import com.mogo.map.marker.IMogoMarkerClickListener; +import com.mogo.map.marker.IMogoMarkerIconViewCreator; +import com.mogo.map.marker.MogoMarkerOptions; +import com.mogo.map.marker.anim.OnMarkerAnimationListener; +import com.mogo.utils.WindowUtils; +import com.mogo.utils.logger.Logger; + +import java.util.ArrayList; +import java.util.List; +import java.util.Observable; +import java.util.Observer; + +/** + * @author congtaowang + * @since 2019-12-18 + *

+ * 高德marker + */ +public class AMapMarkerWrapper implements IMogoMarker, Observer { + + private final String TAG = AMapMarkerWrapper.class.getName(); + + private Marker mMarker; + private Object mObject; + private IMogoMarkerClickListener mMogoMarkerClickListener; + private IMogoInfoWindowAdapter mMogoInfoWindowAdapter; + + private boolean mIsDestroy = false; + + private MogoMarkerOptions mMogoMarkerOptions; + private String mOwner; + + private MovingPointOverlay mMovingPointOverlay; + + public AMapMarkerWrapper( Marker marker, MogoMarkerOptions mogoMarkerOptions ) { + this.mMarker = marker; + if ( marker != null ) { + // 设置高德 marker 的object对象为 IMogoMarker 实例。!!!! + marker.setObject( this ); + } + setObject( mogoMarkerOptions.getObject() ); + this.mMogoMarkerOptions = mogoMarkerOptions; + mMogoMarkerOptions.addObserver( this ); + } + + @Override + public void update( Observable o, Object arg ) { + if ( isDestroyed() ) { + return; + } + setMarkerOptions( mMogoMarkerOptions ); + } + + @Override + public void destroy() { + if ( mMogoMarkerOptions != null ) { + mMogoMarkerOptions.deleteObservers(); + mMogoMarkerOptions = null; + } + if ( mMarker != null ) { + mMarker.remove(); + mMarker.setObject( null ); + mMarker = null; + } + if ( mMovingPointOverlay != null ) { + try { + mMovingPointOverlay.stopMove(); + mMovingPointOverlay.destroy(); + } catch ( Exception e ) { + e.printStackTrace(); + } + mMovingPointOverlay = null; + } + mMogoInfoWindowAdapter = null; + mMogoMarkerClickListener = null; + mObject = null; + mIsDestroy = true; + } + + @Override + public void remove() { + destroy(); + } + + @Override + public void hideInfoWindow() { + if ( mMarker != null ) { + mMarker.hideInfoWindow(); + } + } + + @Override + public void setAlpha( float alpha ) { + if ( mMarker != null ) { + mMarker.setAlpha( alpha ); + } + } + + @Override + public void setAnchor( float anchorU, float anchorV ) { + if ( mMarker != null ) { + mMarker.setAnchor( anchorU, anchorV ); + } + } + + @Override + public void setDraggable( boolean paramBoolean ) { + if ( mMarker != null ) { + mMarker.setDraggable( paramBoolean ); + } + } + + @Override + public void setIcon( Bitmap icon ) { + if ( icon == null || icon.isRecycled() ) { + return; + } + if ( mMarker != null ) { + mMarker.setIcon( BitmapDescriptorFactory.fromBitmap( icon ) ); + } + } + + @Override + public void setIcons( ArrayList< Bitmap > icons ) { + if ( icons == null || icons.isEmpty() ) { + return; + } + ArrayList< BitmapDescriptor > descriptors = new ArrayList<>(); + for ( Bitmap icon : icons ) { + if ( icon == null || icon.isRecycled() ) { + continue; + } + descriptors.add( BitmapDescriptorFactory.fromBitmap( icon ) ); + } + if ( descriptors.isEmpty() ) { + return; + } + if ( mMarker != null ) { + mMarker.setIcons( descriptors ); + } + } + + @Override + public void setInfoWindowEnable( boolean enabled ) { + if ( mMarker != null ) { + mMarker.setInfoWindowEnable( enabled ); + } + } + + @Override + public void setMarkerOptions( MogoMarkerOptions opt ) { + + final MarkerOptions options = ObjectUtils.fromMogo( opt ); + if ( options == null ) { + return; + } + if ( mMarker != null ) { + mMarker.setMarkerOptions( options ); + setObject( opt.getObject() ); + } + } + + @Override + public void setObject( Object object ) { + mObject = object; + } + + @Override + public Object getObject() { + return mObject; + } + + @Override + public void setPeriod( int period ) { + if ( mMarker != null ) { + mMarker.setPeriod( period ); + } + } + + @Override + public void setPosition( double lat, double lng ) { + if ( mMarker != null ) { + mMarker.setPosition( new LatLng( lat, lng ) ); + } + } + + @Override + public MogoLatLng getPosition() { + if ( mMarker != null ) { + final LatLng latLng = mMarker.getPosition(); + return ObjectUtils.fromAMap( latLng ); + } + return null; + } + + @Override + public void setRotateAngle( float rotate ) { + if ( mMarker != null ) { + mMarker.setRotateAngle( rotate ); + } + } + + @Override + public void setSnippet( String snippet ) { + if ( mMarker != null ) { + mMarker.setSnippet( snippet ); + } + } + + @Override + public void setTitle( String title ) { + if ( mMarker != null ) { + mMarker.setTitle( title ); + } + } + + @Override + public void setToTop() { + if ( mMarker != null ) { + mMarker.setToTop(); + } + } + + @Override + public void setVisible( boolean visible ) { + if ( mMarker != null ) { + mMarker.setVisible( visible ); + } + } + + @Override + public void setZIndex( int zIndex ) { + if ( mMarker != null ) { + mMarker.setZIndex( zIndex ); + } + } + + @Override + public void showInfoWindow() { + if ( mMarker != null ) { + mMarker.showInfoWindow(); + } + } + + @Override + public void setOnMarkerClickListener( IMogoMarkerClickListener listener ) { + mMogoMarkerClickListener = listener; + } + + @Override + public IMogoMarkerClickListener getOnMarkerClickListener() { + return mMogoMarkerClickListener; + } + + @Override + public void setInfoWindowAdapter( IMogoInfoWindowAdapter adapter ) { + mMogoInfoWindowAdapter = adapter; + } + + @Override + public IMogoInfoWindowAdapter getInfoWindowAdapter() { + return mMogoInfoWindowAdapter; + } + + @Override + public void setMarkerIconView( IMogoMarkerIconViewCreator creator ) { + if ( creator != null ) { + View iconView = creator.createView( this ); + if ( iconView != null ) { + mMarker.setIcon( BitmapDescriptorFactory.fromView( iconView ) ); + } + } + } + + @Override + public boolean isDestroyed() { + return mIsDestroy; + } + + @Override + public void setOwner( String mOwner ) { + this.mOwner = mOwner; + } + + @Override + public String getOwner() { + if ( mOwner != null ) { + return mOwner; + } + if ( mMogoMarkerOptions != null ) { + return mMogoMarkerOptions.getOwner(); + } + return null; + } + + @Override + public void setPositionByPixels( Point position ) { + if ( mMarker != null ) { + mMarker.setPositionByPixels( position.x, position.y ); + } + } + + public Marker getMarker() { + return mMarker; + } + + @Override + public MogoMarkerOptions getMogoMarkerOptions() { + return mMogoMarkerOptions; + } + + @Override + public void startScaleAnimation( float fromX, float toX, float fromY, float toY, int duration, Interpolator interpolator ) { + if ( isDestroyed() ) { + return; + } + + ScaleAnimation animationScale = new ScaleAnimation( fromX, toX, fromY, toY ); + animationScale.setDuration( duration ); + animationScale.setFillMode( Animation.FILL_MODE_FORWARDS ); + animationScale.setInterpolator( interpolator ); + + mMarker.setAnimation( animationScale ); + mMarker.startAnimation(); + } + + @Override + public void startScaleAnimation( float fromX, float toX, float fromY, float toY, int duration, Interpolator interpolator, OnMarkerAnimationListener listener ) { + if ( isDestroyed() ) { + return; + } + + ScaleAnimation animationScale = new ScaleAnimation( fromX, toX, fromY, toY ); + animationScale.setDuration( duration ); + animationScale.setFillMode( Animation.FILL_MODE_FORWARDS ); + animationScale.setInterpolator( interpolator ); + animationScale.setAnimationListener( new Animation.AnimationListener() { + @Override + public void onAnimationStart() { + if ( isDestroyed() ) { + return; + } + if ( listener != null ) { + listener.onAnimStart(); + } + } + + @Override + public void onAnimationEnd() { + if ( isDestroyed() ) { + return; + } + if ( listener != null ) { + listener.onAnimEnd(); + } + } + } ); + + mMarker.setAnimation( animationScale ); + mMarker.startAnimation(); + } + + @Override + public void startScaleAnimationWithAlpha( float fromX, float toX, float fromY, float toY, float fromAlpha, float toAlpha, int duration, Interpolator interpolator, OnMarkerAnimationListener listener ) { + if ( isDestroyed() ) { + return; + } + + ScaleAnimation animationScale = new ScaleAnimation( fromX, toX, fromY, toY ); + animationScale.setFillMode( Animation.FILL_MODE_FORWARDS ); + + AlphaAnimation alphaAnimation = new AlphaAnimation( fromAlpha, toAlpha ); + alphaAnimation.setFillMode( Animation.FILL_MODE_FORWARDS ); + + AnimationSet animationSet = new AnimationSet( true ); + animationSet.setDuration( duration ); + animationSet.setInterpolator( interpolator); + animationSet.setAnimationListener( new Animation.AnimationListener() { + @Override + public void onAnimationStart() { + if ( isDestroyed() ) { + return; + } + if ( listener != null ) { + listener.onAnimStart(); + } + } + + @Override + public void onAnimationEnd() { + if ( isDestroyed() ) { + return; + } + if ( listener != null ) { + listener.onAnimEnd(); + } + } + } ); + + mMarker.setAnimation( animationSet ); + mMarker.startAnimation(); + } + + @Override + public void startJumpAnimation( float high, long duration, Interpolator interpolator, OnMarkerAnimationListener listener ) { + if ( isDestroyed() || high <= 0.0f || interpolator == null || duration < 0 ) { + return; + } + try { + final LatLng latLng = ObjectUtils.fromMogo2( getPosition() ); + Point point = AMapWrapper.getAMap().getProjection().toScreenLocation( latLng ); + point.y -= WindowUtils.dip2px( AbsMogoApplication.getApp(), high ); + LatLng target = AMapWrapper.getAMap().getProjection().fromScreenLocation( point ); + //使用TranslateAnimation,填写一个需要移动的目标点 + Animation animation = new TranslateAnimation( target ); + animation.setInterpolator( interpolator ); + animation.setAnimationListener( new Animation.AnimationListener() { + @Override + public void onAnimationStart() { + if ( isDestroyed() ) { + return; + } + if ( listener != null ) { + listener.onAnimStart(); + } + } + + @Override + public void onAnimationEnd() { + if ( isDestroyed() ) { + return; + } + if ( listener != null ) { + listener.onAnimEnd(); + } + } + } ); + //整个移动所需要的时间 + animation.setDuration( duration ); + //设置动画 + mMarker.setAnimation( animation ); + mMarker.startAnimation(); + } catch ( Exception e ) { + Logger.e( TAG, e, "error." ); + } + } + + @Override + public void setClickable( boolean clickable ) { + if ( mMarker != null ) { + mMarker.setClickable( clickable ); + } + } + + @Override + public void startSmooth( List< MogoLatLng > points, int duration ) { + + if ( isDestroyed() ) { + return; + } + + if ( mMarker == null ) { + return; + } + + if ( points == null || points.isEmpty() ) { + return; + } + + List< LatLng > newPoints = new ArrayList<>(); + for ( int i = 0; i < points.size(); i++ ) { + LatLng point = ObjectUtils.fromMogo2( points.get( i ) ); + if ( point == null ) { + continue; + } + newPoints.add( point ); + } + if ( newPoints.isEmpty() ) { + return; + } + if ( mMovingPointOverlay == null ) { + mMovingPointOverlay = new MovingPointOverlay( AMapWrapper.getAMap(), mMarker ); + } + mMovingPointOverlay.setPoints( newPoints ); + mMovingPointOverlay.setTotalDuration( duration ); + mMovingPointOverlay.startSmoothMove(); + } + +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/marker/CombineMovingPointOverlay.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/marker/CombineMovingPointOverlay.java new file mode 100644 index 0000000000..4d7d1fb929 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/marker/CombineMovingPointOverlay.java @@ -0,0 +1,330 @@ +package com.mogo.map.impl.amap.marker; + +import com.amap.api.maps.AMap; +import com.amap.api.maps.AMapUtils; +import com.amap.api.maps.model.BasePointOverlay; +import com.amap.api.maps.model.LatLng; +import com.autonavi.amap.mapcore.IPoint; +import com.autonavi.amap.mapcore.MapProjection; +import com.mogo.utils.logger.Logger; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @author congtaowang + * @since 2020/6/15 + *

+ */ +class CombineMovingPointOverlay { + + private static final String TAG = "CombineMovingPointOverlay"; + + private AMap mAMap; + private long mDuration = 1_000L; + private long mStepDuration = 20L; + private LinkedList< LatLng > mPoints = new LinkedList<>(); + private LinkedList< Double > mEachDistance = new LinkedList<>(); + + private double mTotalDistance = 0.0D; + private double mRemainDistance = 0.0D; + private ExecutorService mThreadPools; + private Object mLock = new Object(); + private BasePointOverlay mBaseOverlay = null; + private int mIndex = 0; + private boolean mUseDefaultDescriptor = false; + AtomicBoolean mExitFlag = new AtomicBoolean( false ); + private MoveListener mMoveListener; + private Status mStatus; + private long mPauseMillis; + private long mAnimationBeginTime; + + public CombineMovingPointOverlay( AMap amap, BasePointOverlay baseOverlay ) { + mStatus = Status.Status1; + mAnimationBeginTime = System.currentTimeMillis(); + if ( amap != null && baseOverlay != null ) { + this.mAMap = amap; + this.mBaseOverlay = baseOverlay; + mThreadPools = new ThreadPoolExecutor( 1, 2, 5L, TimeUnit.SECONDS, new SynchronousQueue(), new ThreadFactoryImpl() ); + } + } + + public void setMoveListener( MoveListener moveListener ) { + this.mMoveListener = moveListener; + } + + public void setPoints( List< LatLng > list ) { + synchronized ( mLock ) { + if ( list != null && list.size() >= 2 ) { + stopMove(); + if ( mPoints != null ) { + mPoints.clear(); + } + Iterator< LatLng > iterator = list.listIterator(); + while ( iterator.hasNext() ) { + LatLng latLng = iterator.next(); + if ( latLng != null ) { + mPoints.add( latLng ); + } + } + + mEachDistance.clear(); + mTotalDistance = 0.0D; + + for ( int i = 0; i < mPoints.size(); i++ ) { + double distance = AMapUtils.calculateLineDistance( mPoints.get( i ), mPoints.get( i + 1 ) ); + mEachDistance.add( distance ); + mTotalDistance += distance; + } + + mRemainDistance = mTotalDistance; + mBaseOverlay.setPosition( mPoints.get( 0 ) ); + reset(); + } + } + } + + + public int getIndex() { + return mIndex; + } + + public BasePointOverlay getBaseOverlay() { + return mBaseOverlay; + } + + public void destroy() { + try { + removeMarker(); + mThreadPools.shutdown(); + synchronized ( mLock ) { + mPoints.clear(); + mEachDistance.clear(); + ; + } + } catch ( Exception e ) { + + } + } + + public void removeMarker() { + try { + reset(); + if ( mBaseOverlay != null ) { + mBaseOverlay.remove(); + mBaseOverlay = null; + } + } catch ( Exception e ) { + Logger.e( TAG, e, "error." ); + } + } + + public void stopMove() { + if ( mStatus == Status.Status3 ) { + mStatus = Status.Status4; + mPauseMillis = System.currentTimeMillis(); + } + } + + private void reset() { + if ( mStatus == Status.Status3 || mStatus == Status.Status4 ) { + mExitFlag.set( true ); + try { + mThreadPools.awaitTermination( mStepDuration + 20L, TimeUnit.MICROSECONDS ); + mBaseOverlay.setAnimation( null ); + mStatus = Status.Status1; + } catch ( InterruptedException e ) { + Logger.e( TAG, e, "error." ); + } + } + } + + public void resetIndex() { + mIndex = 0; + } + + + public void setTotalDuration( int seconds ) { + mDuration = seconds * 1_000L; + } + + public void startSmoothMove() { + if ( mStatus == Status.Status4 ) { + mStatus = Status.Status3; + long interval = System.currentTimeMillis() - mPauseMillis; + mAnimationBeginTime += interval; + } else { + if ( mStatus == Status.Status1 || mStatus == Status.Status5 ) { + if ( mPoints.size() <= 0 ) { + return; + } + mIndex = 0; + mThreadPools.execute( new MarkerMovingRunnable() ); + } + } + } + + public void setVisible( boolean visible ) { + if ( mBaseOverlay != null ) { + try { + mBaseOverlay.setVisible( visible ); + } catch ( Exception e ) { + Logger.e( TAG, e, "error." ); + } + } + } + + private class MarkerMovingRunnable implements Runnable { + + @Override + public void run() { + mAnimationBeginTime = System.currentTimeMillis(); + mStatus = Status.Status2; + mExitFlag.set( false ); + + try { + for ( ; !mExitFlag.get() && mIndex <= mPoints.size() - 1; Thread.sleep( mStepDuration ) ) { + synchronized ( mLock ) { + if ( mExitFlag.get() ) { + return; + } + if ( mStatus == Status.Status4 ) { + long interval = System.currentTimeMillis() - mAnimationBeginTime; + IPoint point = getCurPosition( interval ); + mBaseOverlay.setGeoPoint( point ); + mStatus = Status.Status3; + } + } + } + mStatus = Status.Status5; + } catch ( Exception e ) { + Logger.e( TAG, e, "error." ); + } + } + } + + private IPoint getCurPosition( long interval ) { + if ( interval > mDuration ) { + mExitFlag.set( true ); + IPoint point = new IPoint(); + mIndex = mPoints.size() - 1; + LatLng latLng = mPoints.get( mIndex ); + --mIndex; + mIndex = Math.max( mIndex, 0 ); + mRemainDistance = 0.0D; + MapProjection.lonlat2Geo( latLng.longitude, latLng.latitude, point ); + if ( mMoveListener != null ) { + mMoveListener.move( mRemainDistance ); + } + return point; + } else { + double step = interval * mTotalDistance / mDuration; + mRemainDistance = mTotalDistance - step; + int targetIndex = 0; + double val = 1.0D; + + for ( int i = 0; i < mEachDistance.size(); i++ ) { + double distance = mEachDistance.get( i ); + if ( step <= distance ) { + if ( distance > 0.0D ) { + val = step / distance; + } + targetIndex = i; + break; + } + step -= distance; + } + + if ( targetIndex != mIndex && mMoveListener != null ) { + mMoveListener.move( mRemainDistance ); + } + + mIndex = targetIndex; + LatLng latLng = mPoints.get( mIndex ); + LatLng latLng1 = mPoints.get( mIndex + 1 ); + IPoint point = new IPoint(); + MapProjection.lonlat2Geo( latLng.longitude, latLng.latitude, point ); + IPoint point1 = new IPoint(); + MapProjection.lonlat2Geo( latLng1.longitude, latLng1.latitude, point1 ); + + int xDelta = point1.x - point.x; + int yDelta = point1.y - point.y; + + if ( AMapUtils.calculateLineDistance( latLng, latLng1 ) > 1.0F ) { + float rotate = getRotate( point, point1 ); + setRotate( rotate ); + } + return new IPoint( ( ( int ) ( point.x + ( ( double ) xDelta ) * val ) ), ( ( int ) ( point.y + ( ( double ) yDelta ) * val ) ) ); + } + } + + private float getRotate( IPoint point, IPoint point1 ) { + if ( point != null && point1 != null ) { + double py1 = ( double ) point1.y; + double py = ( double ) point.y; + double px = ( double ) point.x; + return ( float ) ( Math.atan2( ( double ) point1.x - px, py - py1 ) / 3.141592653589793D * 180.0D ); + } else { + return 0.0F; + } + } + + public void setPoint( LatLng latLng ) { + if ( mBaseOverlay != null ) { + try { + mBaseOverlay.setPosition( latLng ); + } catch ( Exception e ) { + Logger.e( TAG, e, "error." ); + } + } + } + + public void setRotate( float rotate ) { + if ( mBaseOverlay == null ) { + return; + } + if ( mAMap == null ) { + return; + } + if ( mAMap.getCameraPosition() == null ) { + return; + } + mBaseOverlay.setRotateAngle( 360.0F - rotate + mAMap.getCameraPosition().bearing ); + } + + public LatLng getPosition() { + if ( mBaseOverlay != null ) { + return mBaseOverlay.getPosition(); + } + return null; + } + + private enum Status { + Status1, + Status2, + Status3, + Status4, + Status5 + } + + public interface MoveListener { + void move( double val ); + } + + private static class ThreadFactoryImpl implements ThreadFactory { + + private static int mCounter = 1; + + @Override + public Thread newThread( Runnable r ) { + return new Thread( r, "MoveSmoothThread - " + mCounter++ ); + } + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/message/AMapMessageConsts.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/message/AMapMessageConsts.java new file mode 100644 index 0000000000..37fb4c056f --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/message/AMapMessageConsts.java @@ -0,0 +1,30 @@ +package com.mogo.map.impl.amap.message; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; + +import androidx.annotation.NonNull; + +/** + * @author congtaowang + * @since 2019-12-28 + *

+ * 描述 + */ +public class AMapMessageConsts { + + /** + * 导航开始 + */ + public static final int MSG_NAVI_START = 1000; + /** + * 取消导航 + */ + public static final int MSG_NAVI_STOP = 1001; + /** + * 规划路线成功 + */ + public static final int MSG_CALCULATE_SUCCESS = 1002; + +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/message/AMapMessageListener.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/message/AMapMessageListener.java new file mode 100644 index 0000000000..d183bd1124 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/message/AMapMessageListener.java @@ -0,0 +1,20 @@ +package com.mogo.map.impl.amap.message; + +import com.amap.api.navi.model.NaviInfo; + +/** + * @author congtaowang + * @since 2019-12-28 + *

+ * 消息回调 + */ +public interface AMapMessageListener { + + void onNaviStarted(); + + void onNaviStopped(); + + void onNaviInfoUpdat( NaviInfo naviInfo ); + + void onCalculateSuccess(); +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/message/AMapMessageManager.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/message/AMapMessageManager.java new file mode 100644 index 0000000000..dc3782aadc --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/message/AMapMessageManager.java @@ -0,0 +1,134 @@ +package com.mogo.map.impl.amap.message; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; + +import androidx.annotation.NonNull; + +import com.amap.api.navi.model.NaviInfo; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-28 + *

+ * 描述 + */ +public class AMapMessageManager { + + private static volatile AMapMessageManager sInstance; + + private List< AMapMessageListener > mListeners = new ArrayList<>(); + + private AMapMessageManager() { + } + + public static AMapMessageManager getInstance() { + if ( sInstance == null ) { + synchronized ( AMapMessageManager.class ) { + if ( sInstance == null ) { + sInstance = new AMapMessageManager(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + public synchronized void registerAMapMessageListener( AMapMessageListener listener ) { + if ( !mListeners.contains( listener ) ) { + mListeners.add( listener ); + } + } + + public synchronized void unregisterAMapMessageListener( AMapMessageListener listener ) { + mListeners.remove( listener ); + } + + private Handler mHandler = new Handler( Looper.getMainLooper() ) { + @Override + public void handleMessage( @NonNull Message msg ) { + super.handleMessage( msg ); + AMapMessageManager.this.handleMessage( msg ); + } + }; + + public void sendMessage( Message msg ) { + if ( msg != null ) { + mHandler.sendMessage( msg ); + } + } + + public void sendMessage( int what ) { + sendMessage( what, null ); + } + + public void sendMessage( int what, Object obj ) { + Message msg = Message.obtain(); + msg.what = what; + msg.obj = obj; + sendMessage( msg ); + } + + public void postNaviStarted() { + sendMessage( AMapMessageConsts.MSG_NAVI_START ); + } + + public void postNaviStopped() { + sendMessage( AMapMessageConsts.MSG_NAVI_STOP ); + } + + public void postCalculateSuccess() { + sendMessage( AMapMessageConsts.MSG_CALCULATE_SUCCESS ); + } + + private synchronized void handleMessage( Message msg ) { + if ( msg == null ) { + return; + } + switch ( msg.what ) { + case AMapMessageConsts.MSG_NAVI_START: + handleNaviStartedMsg(); + break; + case AMapMessageConsts.MSG_NAVI_STOP: + handleNaviStoppedMsg(); + break; + case AMapMessageConsts.MSG_CALCULATE_SUCCESS: + handleCalculateSuccessMsg(); + break; + } + } + + private void handleNaviStartedMsg() { + if ( mListeners == null ) { + return; + } + for ( AMapMessageListener listener : mListeners ) { + listener.onNaviStarted(); + } + } + + private void handleNaviStoppedMsg() { + if ( mListeners == null ) { + return; + } + for ( AMapMessageListener listener : mListeners ) { + listener.onNaviStopped(); + } + } + + private void handleCalculateSuccessMsg() { + if ( mListeners == null ) { + return; + } + for ( AMapMessageListener listener : mListeners ) { + listener.onCalculateSuccess(); + } + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/AMapNaviListenerAdapter.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/AMapNaviListenerAdapter.java new file mode 100644 index 0000000000..ab14875e9e --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/AMapNaviListenerAdapter.java @@ -0,0 +1,241 @@ +package com.mogo.map.impl.amap.navi; + +import com.amap.api.navi.AMapNaviListener; +import com.amap.api.navi.model.AMapCalcRouteResult; +import com.amap.api.navi.model.AMapLaneInfo; +import com.amap.api.navi.model.AMapModelCross; +import com.amap.api.navi.model.AMapNaviCameraInfo; +import com.amap.api.navi.model.AMapNaviCross; +import com.amap.api.navi.model.AMapNaviInfo; +import com.amap.api.navi.model.AMapNaviLocation; +import com.amap.api.navi.model.AMapNaviRouteNotifyData; +import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo; +import com.amap.api.navi.model.AMapServiceAreaInfo; +import com.amap.api.navi.model.AimLessModeCongestionInfo; +import com.amap.api.navi.model.AimLessModeStat; +import com.amap.api.navi.model.NaviInfo; +import com.autonavi.tbt.TrafficFacilityInfo; +import com.mogo.commons.AbsMogoApplication; +import com.mogo.commons.voice.AIAssist; +import com.mogo.map.MogoLatLng; +import com.mogo.utils.logger.Logger; +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 高德导航事件:导航事件 + */ +public abstract class AMapNaviListenerAdapter implements AMapNaviListener { + + private static final String TAG = "AMapNaviListenerAdapter"; + protected String mLastSpeakWord; + + @Override + public void onInitNaviFailure() { + + } + + @Override + public void onInitNaviSuccess() { + + } + + @Override + public void onStartNavi( int i ) { + + } + + @Override + public void onTrafficStatusUpdate() { + + } + + @Override + public void onLocationChange( AMapNaviLocation aMapNaviLocation ) { + + } + + @Override + public void onGetNavigationText( int i, String s ) { + + } + + @Override + public void onGetNavigationText( String s ) { + mLastSpeakWord = s; + Logger.d( TAG, s ); +// TTSSpeaker.getInstance().speakTTS( s ); + } + + @Override + public void onEndEmulatorNavi() { + + } + + @Override + public void onArriveDestination() { + + } + + @Override + public void onCalculateRouteFailure( int i ) { + + } + + @Override + public void onReCalculateRouteForYaw() { + + } + + @Override + public void onReCalculateRouteForTrafficJam() { + + } + + @Override + public void onArrivedWayPoint( int i ) { + + } + + @Override + public void onGpsOpenStatus( boolean b ) { + + } + + @Override + public void onNaviInfoUpdate( NaviInfo naviInfo ) { + + } + + @Override + public void onNaviInfoUpdated( AMapNaviInfo aMapNaviInfo ) { + + } + + @Override + public void updateCameraInfo( AMapNaviCameraInfo[] aMapNaviCameraInfos ) { + + } + + @Override + public void updateIntervalCameraInfo( AMapNaviCameraInfo aMapNaviCameraInfo, AMapNaviCameraInfo aMapNaviCameraInfo1, int i ) { + if ( aMapNaviCameraInfo != null ) { + Logger.i( TAG, "current camera speed: %d, status = %d", aMapNaviCameraInfo.getCameraSpeed(), i ); + } + if ( aMapNaviCameraInfo1 != null ) { + Logger.i( TAG, "current camera speed: %d, status = %d", aMapNaviCameraInfo1.getCameraSpeed(), i ); + } + } + + + @Override + public void onServiceAreaUpdate( AMapServiceAreaInfo[] aMapServiceAreaInfos ) { + + } + + @Override + public void showCross( AMapNaviCross aMapNaviCross ) { + + } + + @Override + public void hideCross() { + + } + + @Override + public void showModeCross( AMapModelCross aMapModelCross ) { + + } + + @Override + public void hideModeCross() { + + } + + @Override + public void showLaneInfo( AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1 ) { + + } + + @Override + public void showLaneInfo( AMapLaneInfo aMapLaneInfo ) { + + } + + @Override + public void hideLaneInfo() { + + } + + @Override + public void onCalculateRouteSuccess( int[] ints ) { + + } + + @Override + public void notifyParallelRoad( int i ) { + + } + + @Override + public void OnUpdateTrafficFacility( AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos ) { + + } + + @Override + public void OnUpdateTrafficFacility( AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo ) { + + } + + @Override + public void OnUpdateTrafficFacility( TrafficFacilityInfo trafficFacilityInfo ) { + + } + + /** + * 巡航回调 + * 连续5个点速度大于15km/h后触发 updateAimlessModeStatistics 回调,通过 AimLessModeStat 对象可获取巡航的连续行驶距离和连续启用时间 + * + * @param aimLessModeStat + */ + @Override + public void updateAimlessModeStatistics( AimLessModeStat aimLessModeStat ) { + + } + + /** + * 巡航回调 + * 出现拥堵长度大于500米且拥堵时间大于5分钟时,会进到 updateAimlessModeCongestionInfo 回调中,通过 AimLessModeCongestionInfo 对象,可获取到道路拥堵信息(如:导致拥堵的事件类型、拥堵的状态等) + * + * @param aimLessModeCongestionInfo + */ + @Override + public void updateAimlessModeCongestionInfo( AimLessModeCongestionInfo aimLessModeCongestionInfo ) { + + } + + @Override + public void onPlayRing( int i ) { + + } + + @Override + public void onCalculateRouteSuccess( AMapCalcRouteResult aMapCalcRouteResult ) { + + } + + @Override + public void onCalculateRouteFailure( AMapCalcRouteResult aMapCalcRouteResult ) { + + } + + @Override + public void onNaviRouteNotify( AMapNaviRouteNotifyData aMapNaviRouteNotifyData ) { + + } + + +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/AimlessModeListenerAdapter.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/AimlessModeListenerAdapter.java new file mode 100644 index 0000000000..cdb8583fd3 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/AimlessModeListenerAdapter.java @@ -0,0 +1,48 @@ +package com.mogo.map.impl.amap.navi; + +import com.amap.api.navi.AimlessModeListener; +import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo; +import com.amap.api.navi.model.AimLessModeCongestionInfo; +import com.amap.api.navi.model.AimLessModeStat; +import com.mogo.map.impl.amap.utils.ObjectUtils; +import com.mogo.map.navi.MogoCongestionInfo; +import com.mogo.map.navi.MogoNaviListenerHandler; +import com.mogo.map.navi.MogoTraffic; + +/** + * @author congtaowang + * @since 2020-01-16 + *

+ * 巡航监听 + */ +public class AimlessModeListenerAdapter implements AimlessModeListener { + + @Override + public void onUpdateTrafficFacility( AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos ) { + MogoTraffic traffic = ObjectUtils.fromAMap( aMapNaviTrafficFacilityInfos ); + if ( traffic != null ) { + MogoNaviListenerHandler.getInstance().onUpdateTraffic2( traffic ); + } + } + + @Override + public void onUpdateAimlessModeElecCameraInfo( AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos ) { + MogoTraffic traffic = ObjectUtils.fromAMap( aMapNaviTrafficFacilityInfos ); + if ( traffic != null ) { + MogoNaviListenerHandler.getInstance().onUpdateTraffic2( traffic ); + } + } + + @Override + public void updateAimlessModeStatistics( AimLessModeStat aimLessModeStat ) { + + } + + @Override + public void updateAimlessModeCongestionInfo( AimLessModeCongestionInfo aimLessModeCongestionInfo ) { + MogoCongestionInfo congestionInfo = ObjectUtils.fromAMap( aimLessModeCongestionInfo ); + if ( congestionInfo != null ) { + MogoNaviListenerHandler.getInstance().onUpdateCongestion( congestionInfo ); + } + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/CalculatePathItem.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/CalculatePathItem.java new file mode 100644 index 0000000000..8a705ce576 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/CalculatePathItem.java @@ -0,0 +1,181 @@ +package com.mogo.map.impl.amap.navi; + +import android.content.Context; +import android.text.TextUtils; + +import com.amap.api.maps.AMap; +import com.amap.api.navi.model.AMapNaviPath; +import com.amap.api.navi.model.AMapNaviStep; +import com.amap.api.navi.model.NaviLatLng; +import com.mogo.map.MogoLatLng; +import com.mogo.map.impl.amap.overlay.RouteOverLayWrapper; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-04 + *

+ * 导航路径代理类 + */ +public class CalculatePathItem { + + private Context mContext; + private AMap mAMap; + private int mId; + private AMapNaviPath mPath; + + private RouteOverLayWrapper mOverLazWrapper; + private ArrayList< MogoLatLng > mPoints; + + public int getId() { + return mId; + } + + public AMapNaviPath getPath() { + return mPath; + } + + public RouteOverLayWrapper getOverLazWrapper( boolean createIfNull ) { + if ( mOverLazWrapper == null && createIfNull ) { + mOverLazWrapper = new RouteOverLayWrapper( mContext, mAMap, mPath ); + } + return mOverLazWrapper; + } + + public CalculatePathItem( Context context, AMap amap, int id, AMapNaviPath path ) { + mContext = context; + mAMap = amap; + this.mId = id; + this.mPath = path; + } + + public String getStrategyName() { + return mPath.getLabels(); + } + + public String getFormattedTime() { + if ( mTimeBuilder == null ) { + final int time = mPath.getAllTime(); + mTimeBuilder = new StringBuilder(); + fillFormatTime( time, mTimeBuilder ); + } + return mTimeBuilder.toString(); + } + + public int getTime(){ + return mPath.getAllTime(); + } + + public int getDistance(){ + return mPath.getAllLength(); + } + + private StringBuilder mTimeBuilder; + + private void fillFormatTime( int seconds, StringBuilder builder ) { + // int days = seconds / ( 24 * 60 * 60 ); + // if ( days > 0 ) { + // builder.append( days ).append( "天" ); + // } + // seconds -= days * 24 * 60 * 60; + int hours = seconds / ( 60 * 60 ); + if ( hours > 0 ) { + builder.append( hours ).append( "小时" ); + } + seconds -= hours * 60 * 60; + int min = seconds / 60; + builder.append( min > 1 ? min : 1 ).append( "分钟" ); + } + + private String mDistanceCacheStr = ""; + + public String getFormattedDistance() { + if ( TextUtils.isEmpty( mDistanceCacheStr ) ) { + int distance = mPath.getAllLength(); + if ( distance == -1 ) { + mDistanceCacheStr = "路程总程未获取"; + } + if ( distance >= 1000 ) { + mDistanceCacheStr = String.format( "%.1f公里", ( float ) distance / 1000 ); + } else { + mDistanceCacheStr = distance + "米"; + } + } + return mDistanceCacheStr; + } + + private StringBuilder mDescBuilder = null; + + public String getDesc() { + if ( mDescBuilder == null ) { + mDescBuilder = new StringBuilder(); + int lightsSize = getTrafficNumber(); + if ( lightsSize > 0 ) { + mDescBuilder.append( "红绿灯" ).append( lightsSize ).append( "个" ); + } + mDescBuilder.append( " " ); + mDescBuilder.append( "收费" ).append( mPath.getTollCost() ).append( "元" ); + } + + return mDescBuilder.toString(); + } + + public int getTrafficNumber() { + int trafficLightNumber = 0; + if ( mPath == null ) { + return trafficLightNumber; + } + List< AMapNaviStep > steps = mPath.getSteps(); + for ( AMapNaviStep step : steps ) { + trafficLightNumber += step.getTrafficLightNumber(); + } + return trafficLightNumber; + } + + public void release() { + mContext = null; + mAMap = null; + mPath = null; + if ( mOverLazWrapper != null ) { + mOverLazWrapper.destroy(); + } + mOverLazWrapper = null; + if ( mPoints != null ) { + mPoints.clear(); + } + mPoints = null; + } + + public List< MogoLatLng > getCoordList() { + if ( mPoints == null ) { + mPoints = new ArrayList<>(); + for ( NaviLatLng latlng : mPath.getCoordList() ) { + MogoLatLng mogoLatLng = new MogoLatLng( latlng.getLatitude(), latlng.getLongitude() ); + mPoints.add( mogoLatLng ); + } + } + return mPoints; + } + + public MogoLatLng getDriveStartPoint() { + if ( mPath != null && mPath.getCoordList() != null && mPath.getCoordList().size() > 0 ) { + NaviLatLng startPoint = mPath.getCoordList().get( 0 ); + if ( startPoint != null ) { + return new MogoLatLng( startPoint.getLatitude(), startPoint.getLongitude() ); + } + } + return null; + } + + public MogoLatLng getDriveEndPoint() { + if ( mPath != null && mPath.getCoordList() != null && mPath.getCoordList().size() > 0 ) { + NaviLatLng endPoint = mPath.getCoordList().get( mPath.getCoordList().size() - 1 ); + if ( endPoint != null ) { + return new MogoLatLng( endPoint.getLatitude(), endPoint.getLongitude() ); + } + } + return null; + } +} \ No newline at end of file diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/NaviClient.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/NaviClient.java new file mode 100644 index 0000000000..963a177155 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/NaviClient.java @@ -0,0 +1,386 @@ +package com.mogo.map.impl.amap.navi; + +import android.content.Context; +import android.graphics.Rect; +import android.location.Location; + +import com.amap.api.maps.LocationSource; +import com.amap.api.maps.model.Polyline; +import com.amap.api.navi.AMapNavi; +import com.amap.api.navi.enums.AimLessMode; +import com.amap.api.navi.enums.NaviType; +import com.amap.api.navi.model.NaviLatLng; +import com.mogo.commons.AbsMogoApplication; +import com.mogo.commons.debug.DebugConfig; +import com.mogo.commons.voice.AIAssist; +import com.mogo.map.MogoLatLng; +import com.mogo.map.impl.amap.AMapWrapper; +import com.mogo.map.impl.amap.message.AMapMessageManager; +import com.mogo.map.impl.amap.utils.ObjectUtils; +import com.mogo.map.navi.IMogoCarLocationChangedListener; +import com.mogo.map.navi.IMogoCarLocationChangedListener2; +import com.mogo.map.navi.IMogoNavi; +import com.mogo.map.navi.MogoCalculatePath; +import com.mogo.map.navi.MogoNaviConfig; +import com.mogo.map.navi.MogoNaviListenerHandler; +import com.mogo.map.navi.OnCalculatePathItemClickInteraction; +import com.mogo.utils.logger.Logger; +import com.mogo.utils.storage.SharedPrefsMgr; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 高德导航 + */ +public class NaviClient implements IMogoNavi { + + /** + * 巡航状态控制 + */ + public static final String KEY_AIMLESS_STATUS = "KEY_AIMLESS_STATUS"; + + private static final String TAG = "NaviClient"; + private final Context mContext; + + private AMapNavi mAMapNavi; + private final NaviListenerAdapter mAMapNaviListener; + + + private final AimlessModeListenerAdapter mAimlessModeListener; + + /** + * 导航策略配置 + */ + + private MogoNaviConfig mMogoNaviConfig = new MogoNaviConfig(); + + private static volatile NaviClient sInstance; + private boolean mIsRealNavi; + + private Location mCarLocation; + private IMogoCarLocationChangedListener2 mCarLocationChangedListener; + private LocationSource.OnLocationChangedListener mOnLocationChangedListener; + /** + * 巡航模式配置状态 + */ + private boolean mAimlessModeStatus; + + /** + * 巡航状态 + */ + private boolean mAimlessStatus; + + private NaviClient( Context context ) { + mContext = context; + mAMapNavi = AMapNavi.getInstance( context ); + mAMapNavi.setEmulatorNaviSpeed( 120 ); + mAMapNavi.setUseInnerVoice( DebugConfig.isUseCustomNavi(), true ); + mAMapNaviListener = new NaviListenerAdapter( context, mAMapNavi, this ); + mAimlessModeListener = new AimlessModeListenerAdapter() { + }; + mAMapNavi.addAMapNaviListener( mAMapNaviListener ); + mAMapNavi.addAimlessModeListener( mAimlessModeListener ); + mAimlessModeStatus = SharedPrefsMgr.getInstance( mContext ).getBoolean( KEY_AIMLESS_STATUS, false ); + } + + public static NaviClient getInstance( Context context ) { + if ( sInstance == null ) { + synchronized ( NaviClient.class ) { + if ( sInstance == null ) { + sInstance = new NaviClient( context ); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + @Override + public void naviTo( MogoLatLng endPoint ) { + naviTo( endPoint, mMogoNaviConfig ); + } + + @Override + public void naviTo( MogoLatLng endPoint, MogoNaviConfig config ) { + naviTo( endPoint, null, config ); + } + + @Override + public void naviTo( MogoLatLng endPoint, List< MogoLatLng > wayPoints ) { + naviTo( endPoint, wayPoints, mMogoNaviConfig ); + } + + @Override + public void naviTo( MogoLatLng endPoint, List< MogoLatLng > wayPoints, MogoNaviConfig config ) { + if ( !checkAMapNavi() ) { + return; + } + Logger.i( TAG, "开始规划路径" ); + mMogoNaviConfig = config; + if ( mMogoNaviConfig == null ) { + mMogoNaviConfig = new MogoNaviConfig(); + } + int strategy = mAMapNavi.strategyConvert( mMogoNaviConfig.isCongestion(), mMogoNaviConfig.isAvoidSpeed(), mMogoNaviConfig.isCost(), mMogoNaviConfig.isHighSpeed(), config.isMultipleRoute() ); + List< NaviLatLng > naviWayPoints = null; + if ( wayPoints != null && !wayPoints.isEmpty() ) { + naviWayPoints = new ArrayList<>( wayPoints.size() ); + for ( MogoLatLng wayPoint : wayPoints ) { + naviWayPoints.add( ObjectUtils.fromMogoAsNavi( wayPoint ) ); + } + } else { + naviWayPoints = new ArrayList<>(); + } + mAMapNavi.calculateDriveRoute( + new ArrayList( Arrays.asList( ObjectUtils.fromMogoAsNavi( endPoint ) ) ), + naviWayPoints, + strategy + ); + } + + @Override + public void reCalculateRoute( MogoNaviConfig config ) { + if ( !checkAMapNavi() ) { + return; + } + mMogoNaviConfig = config; + if ( mMogoNaviConfig == null ) { + mMogoNaviConfig = new MogoNaviConfig(); + } + int strategy = mAMapNavi.strategyConvert( mMogoNaviConfig.isCongestion(), mMogoNaviConfig.isAvoidSpeed(), mMogoNaviConfig.isCost(), mMogoNaviConfig.isHighSpeed(), config.isMultipleRoute() ); + mAMapNavi.reCalculateRoute( strategy ); + } + + @Override + public void stopNavi() { + if ( mAMapNaviListener != null ) { + mAMapNaviListener.stopNavi(); + } + } + + + @Override + public void startNavi( boolean isRealNavi ) { + if ( mAMapNaviListener.isStopped() ) { + return; + } + mIsRealNavi = isRealNavi; + stopAimlessMode(); + boolean isNaving = isNaviing(); + boolean result = mAMapNavi.startNavi( isRealNavi ? NaviType.GPS : NaviType.EMULATOR ); + if ( isNaving && !result ) { + // 如果正在导航,又重新规划路线,startNavi 不会成功,不会重新回调 #onStartNavi + MogoNaviListenerHandler.getInstance().onStartNavi(); + AMapMessageManager.getInstance().postNaviStarted(); + } + Logger.d( TAG, "start navi status: %s", result ); + } + + @Override + public boolean isNaviing() { + if ( mAMapNaviListener != null ) { + return mAMapNaviListener.isNaviing(); + } + return false; + } + + @Override + public List< MogoCalculatePath > getCalculatedStrategies() { + if ( mAMapNaviListener != null ) { + return mAMapNaviListener.getCalculateStrategies(); + } + return null; + } + + @Override + public List< MogoLatLng > getCalculatedPathPos() { + if ( mAMapNaviListener != null ) { + return mAMapNaviListener.getCalculatedPathPos(); + } + return null; + } + + @Override + public OnCalculatePathItemClickInteraction getItemClickInteraction() { + if ( mAMapNaviListener != null ) { + return mAMapNaviListener.getItemClickInteraction(); + } + return null; + } + + @Override + public void setLineClickInteraction( OnCalculatePathItemClickInteraction lineClickInteraction ) { + if ( mAMapNaviListener != null ) { + mAMapNaviListener.setLineClickInteraction( lineClickInteraction ); + } + } + + @Override + public void clearCalculatePaths() { + if ( mAMapNaviListener != null ) { + mAMapNaviListener.clearCalculatePaths(); + } + } + + @Override + public void setCalculatePathDisplayBounds( Rect bounds ) { + if ( mAMapNaviListener != null ) { + mAMapNaviListener.setCalculatePathDisplayBounds( bounds ); + } + } + + @Override + public MogoNaviConfig getNaviConfig() { + return mMogoNaviConfig; + } + + @Override + public boolean setBroadcastMode( int mode ) { + return mAMapNavi.setBroadcastMode( mode ); + } + + @Override + public List< MogoLatLng > getNaviPathCoordinates() { + return null; + } + + @Override + public MogoLatLng getCarLocation() { + if ( mCarLocation != null ) { + synchronized ( mCarLocation ) { + return new MogoLatLng( mCarLocation.getLatitude(), mCarLocation.getLongitude() ); + } + } + return null; + } + + @Override + public Location getCarLocation2() { + return mCarLocation; + } + + @Override + public void registerCarLocationChangedListener( IMogoCarLocationChangedListener2 listener ) { + mCarLocationChangedListener = listener; + } + + // -- end + + public void syncCarLocation( Location location ) { + mCarLocation = location; + if ( mCarLocationChangedListener != null ) { + mCarLocationChangedListener.onCarLocationChanged2( mCarLocation ); + } + } + + private boolean checkAMapNavi() { + if ( mAMapNavi == null ) { + Logger.e( TAG, "高德导航实例为空!!!" ); + return false; + } + return true; + } + + public boolean isRealNavi() { + return mIsRealNavi; + } + + public void handleClickedPolyline( Polyline polyline ) { + if ( mAMapNaviListener != null ) { + mAMapNaviListener.handleClickedPolyline( polyline ); + } + } + + @Override + public void startAimlessMode() { + if ( mAimlessModeStatus && !isNaviing() ) { + mAMapNavi.startAimlessMode( AimLessMode.CAMERA_AND_SPECIALROAD_DETECTED ); + mAimlessStatus = true; + Logger.d( TAG, "开启巡航成功" ); + } else { + mAimlessStatus = false; + Logger.d( TAG, "开启巡航失败" ); + } + } + + @Override + public void stopAimlessMode() { + mAMapNavi.stopAimlessMode(); + mAimlessStatus = false; + Logger.d( TAG, "关闭巡航成功" ); + } + + @Override + public void setAimlessModeStatus( boolean open ) { + this.mAimlessModeStatus = open; + SharedPrefsMgr.getInstance( mContext ).putBoolean( KEY_AIMLESS_STATUS, open ); + if ( open ) { + if ( !mAimlessStatus ) { + startAimlessMode(); + } + } else { + if ( mAimlessStatus ) { + stopAimlessMode(); + } + } + } + + @Override + public void displayOverview( Rect bounds ) { + if ( mAMapNaviListener != null ) { + mAMapNaviListener.displayOverview( bounds ); + } + } + + @Override + public void setUseExtraGPSData( boolean use ) { + Logger.d( TAG, "设置外部gps源状态 %s", use ); + mAMapNavi.setIsUseExtraGPSData( use ); + if ( AMapWrapper.getAMap() == null ) { + return; + } + if ( use ) { + AMapWrapper.getAMap().setLocationSource( new LocationSource() { + @Override + public void activate( OnLocationChangedListener onLocationChangedListener ) { + NaviClient.this.mOnLocationChangedListener = onLocationChangedListener; + } + + @Override + public void deactivate() { + } + } ); + } else { + AMapWrapper.getAMap().setLocationSource( new com.amap.api.col.n3.dd( AbsMogoApplication.getApp() ) ); + mOnLocationChangedListener = null; + } + AMapWrapper.getAMap().setMyLocationEnabled( true ); + } + + @Override + public void setExtraGPSData( double lon, double lat, float speed, float accuracy, float bearing, long timestamp ) { + if ( !mAMapNavi.getIsUseExtraGPSData() ) { + Logger.d( TAG, "拒绝外部GPS数据" ); + return; + } + Location location = new Location( "外部GPS源" ); + location.setLongitude( lon ); + location.setLatitude( lat ); + location.setSpeed( speed ); + location.setAccuracy( accuracy ); + location.setBearing( bearing ); + location.setTime( timestamp ); + //type字段传1时代表WGS84坐标 + mAMapNavi.setExtraGPSData( 2, location ); + if ( mOnLocationChangedListener != null ) { + mOnLocationChangedListener.onLocationChanged( location ); + } + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/NaviListenerAdapter.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/NaviListenerAdapter.java new file mode 100644 index 0000000000..96578329ed --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/NaviListenerAdapter.java @@ -0,0 +1,302 @@ +package com.mogo.map.impl.amap.navi; + +import android.content.Context; +import android.graphics.Rect; +import android.os.Trace; +import android.text.TextUtils; + +import com.amap.api.maps.model.Polyline; +import com.amap.api.navi.AMapNavi; +import com.amap.api.navi.AimlessModeListener; +import com.amap.api.navi.enums.AimLessMode; +import com.amap.api.navi.enums.CameraType; +import com.amap.api.navi.enums.CarEnterCameraStatus; +import com.amap.api.navi.enums.NaviType; +import com.amap.api.navi.model.AMapCalcRouteResult; +import com.amap.api.navi.model.AMapNaviCameraInfo; +import com.amap.api.navi.model.AMapNaviInfo; +import com.amap.api.navi.model.AMapNaviLocation; +import com.amap.api.navi.model.NaviInfo; +import com.mogo.commons.voice.AIAssist; +import com.mogo.map.MogoLatLng; +import com.mogo.map.impl.amap.AMapWrapper; +import com.mogo.map.impl.amap.message.AMapMessageManager; +import com.mogo.map.impl.amap.utils.ObjectUtils; +import com.mogo.map.navi.MogoCalculatePath; +import com.mogo.map.navi.MogoNaviListenerHandler; +import com.mogo.map.navi.MogoTraffic; +import com.mogo.map.navi.OnCalculatePathItemClickInteraction; +import com.mogo.utils.UiThreadHandler; +import com.mogo.utils.WorkThreadHandler; +import com.mogo.utils.logger.Logger; + +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 高德导航回调 + */ +public class NaviListenerAdapter extends AMapNaviListenerAdapter { + + private static final String TAG = "NaviListenerAdapter"; + + private Context mContext; + private AMapNavi mAMapNavi; + private NaviClient mClient; + /** + * 导航状态:true - 导航 onStartNavi(int) 被调用, false - 到达目的地、手动挺固执 + */ + private boolean mIsNaviing = false; + + /** + * 导航是否被停止:true - 手动停止或到达目的地、false - 规划路径成功、开启导航 + */ + private boolean mIsStopped = true; + + /** + * 路线规划 + */ + private NaviOverlayHelper mNaviOverlayHelper; + + public NaviListenerAdapter( Context mContext, AMapNavi mAMapNavi, NaviClient client ) { + this.mContext = mContext; + this.mAMapNavi = mAMapNavi; + this.mClient = client; + mNaviOverlayHelper = new NaviOverlayHelper( mAMapNavi, AMapWrapper.getAMap(), mContext ); + } + + public void setNaviing( boolean mIsNaviing ) { + this.mIsNaviing = mIsNaviing; + } + + public boolean isNaviing() { + return mIsNaviing; + } + + public void setStopped( boolean isStopped ) { + this.mIsStopped = isStopped; + } + + public boolean isStopped() { + return mIsStopped; + } + + public Context getContext() { + return mContext; + } + + @Override + public void onInitNaviFailure() { + MogoNaviListenerHandler.getInstance().onInitNaviFailure(); + } + + @Override + public void onInitNaviSuccess() { + MogoNaviListenerHandler.getInstance().onInitNaviSuccess(); + NaviClient.getInstance( mContext ).startAimlessMode(); + } + + @Override + public void updateCameraInfo( AMapNaviCameraInfo[] aMapNaviCameraInfos ) { + super.updateCameraInfo( aMapNaviCameraInfos ); + if ( aMapNaviCameraInfos == null || aMapNaviCameraInfos.length == 0 ) { + return; + } + int limitSpeed = 0; + for ( AMapNaviCameraInfo aMapNaviCameraInfo : aMapNaviCameraInfos ) { + if ( aMapNaviCameraInfo == null ) { + continue; + } + limitSpeed = aMapNaviCameraInfo.getCameraSpeed(); + if ( limitSpeed > 0 && aMapNaviCameraInfo.getCameraType() == CameraType.SPEED ) { + MogoTraffic traffic = new MogoTraffic( MogoTraffic.TYPE_NAVI ); + traffic.setDistance( aMapNaviCameraInfo.getCameraDistance() ); + traffic.setSpeedLimit( aMapNaviCameraInfo.getCameraSpeed() ); + MogoNaviListenerHandler.getInstance().onUpdateTraffic2( traffic ); + } + +// switch ( aMapNaviCameraInfo.getCameraType() ) { +// case CameraType.SPEED: +// +// break; +// case CameraType.SURVEILLANCE: +// traffic.setDesc( "监控摄像" ); +// break; +// case CameraType.TRAFFICLIGHT: +// traffic.setDesc( "闯红灯拍照" ); +// break; +// case CameraType.BREAKRULE: +// traffic.setDesc( "违章拍照" ); +// break; +// case CameraType.BUSWAY: +// traffic.setDesc( "公交专用道摄像头" ); +// break; +// case CameraType.EMERGENCY: +// traffic.setDesc( "应急车道拍照" ); +// break; +// case CameraType.BICYCLE: +// traffic.setDesc( "非机动车道" ); +// break; +// case CameraType.INTERVALVELOCITYSTART: +// traffic.setDesc( "区间测速起始" ); +// break; +// case CameraType.INTERVALVELOCITYEND: +// traffic.setDesc( "区间测速解除" ); +// break; +// } + } + if ( limitSpeed <= 0 ) { + MogoTraffic traffic = new MogoTraffic( MogoTraffic.TYPE_NAVI ); + traffic.setDistance( 0 ); + traffic.setSpeedLimit( 0 ); + MogoNaviListenerHandler.getInstance().onUpdateTraffic2( traffic ); + } + } + + @Override + public void onStartNavi( int type ) { + + Logger.d( TAG, "onStartNavi type = %s", type ); + // 巡航 + if ( type != NaviType.CRUISE ) { + setStopped( false ); + setNaviing( true ); + MogoNaviListenerHandler.getInstance().onStartNavi(); + AMapMessageManager.getInstance().postNaviStarted(); + } + } + + @Override + public void onEndEmulatorNavi() { + stopNaviDelay( () -> { + MogoNaviListenerHandler.getInstance().onEndEmulatorNavi(); + } ); + } + + @Override + public void onArriveDestination() { + stopNaviDelay( () -> { + MogoNaviListenerHandler.getInstance().onArriveDestination(); + } ); + } + + /** + * 避免导航结束语音播报被立刻打断的情况 + * + * @param after 停止后的行为 + */ + private void stopNaviDelay( Runnable after ) { + UiThreadHandler.postDelayed( () -> { + if ( TextUtils.isEmpty( mLastSpeakWord ) || !mLastSpeakWord.contains( "结束" ) ) { + AIAssist.getInstance( mContext ).speakTTSVoice( "到达目的地附近,本次导航结束" ); + } + mLastSpeakWord = ""; + stopNavi(); + if ( after != null ) { + after.run(); + } + }, 5_000L ); + } + + @Override + public void onNaviInfoUpdate( NaviInfo naviInfo ) { + Trace.beginSection( "NaviListenerAdapter.onNaviInfoUpdate" ); + MogoNaviListenerHandler.getInstance().onNaviInfoUpdate( ObjectUtils.fromAMap( mContext, naviInfo ) ); + mNaviOverlayHelper.handleNaviInfoUpdate( naviInfo ); + Trace.endSection(); + } + + @Override + public void onCalculateRouteFailure( AMapCalcRouteResult aMapCalcRouteResult ) { + if ( aMapCalcRouteResult != null ) { + Logger.i( TAG, PathPlanningErrorCodeConstants.getErrorMsg( aMapCalcRouteResult.getErrorCode() ) ); + } + MogoNaviListenerHandler.getInstance().onoCalculateFailed(); + } + + @Override + public void onCalculateRouteSuccess( AMapCalcRouteResult aMapCalcRouteResult ) { + super.onCalculateRouteSuccess( aMapCalcRouteResult ); + Logger.i( TAG, "导航规划成功" ); + setStopped( false ); + mNaviOverlayHelper.showCalculatedPaths( () -> { + AMapMessageManager.getInstance().postCalculateSuccess(); + MogoNaviListenerHandler.getInstance().onCalculateSuccess(); + } ); + } + + @Override + public void onLocationChange( AMapNaviLocation aMapNaviLocation ) { + Trace.beginSection( "NaviListenerAdapter.onLocationChange" ); + super.onLocationChange( aMapNaviLocation ); + mNaviOverlayHelper.handlePassedLocation( aMapNaviLocation ); + Trace.endSection(); + } + + public void stopNavi() { + TTSSpeaker.getInstance().shutUp(); + mNaviOverlayHelper.clearCalculatedOverlay(); + setStopped( true ); + setNaviing( false ); + mAMapNavi.stopNavi(); + MogoNaviListenerHandler.getInstance().onStopNavi(); + AMapMessageManager.getInstance().postNaviStopped(); + } + + public void handleClickedPolyline( Polyline polyline ) { + if ( mNaviOverlayHelper != null ) { + + mNaviOverlayHelper.handleClickedPolyline( polyline, isNaviing() ); + mAMapNavi.selectRouteId( mNaviOverlayHelper.getSelectedPathId() ); + mNaviOverlayHelper.showBoundsWithSettingBounds(); + } + } + + public List< MogoCalculatePath > getCalculateStrategies() { + if ( mNaviOverlayHelper != null ) { + return mNaviOverlayHelper.getCalculateStrategies(); + } + return null; + } + + public List< MogoLatLng > getCalculatedPathPos() { + if ( mNaviOverlayHelper != null ) { + return mNaviOverlayHelper.getCalculatedPathPos(); + } + return null; + } + + + public OnCalculatePathItemClickInteraction getItemClickInteraction() { + if ( mNaviOverlayHelper != null ) { + return mNaviOverlayHelper.getItemClickInteraction(); + } + return null; + } + + public void setLineClickInteraction( OnCalculatePathItemClickInteraction lineClickInteraction ) { + if ( mNaviOverlayHelper != null ) { + mNaviOverlayHelper.setLineClickInteraction( lineClickInteraction ); + } + } + + public void clearCalculatePaths() { + if ( mNaviOverlayHelper != null ) { + mNaviOverlayHelper.clearCalculatedOverlay(); + } + } + + public void setCalculatePathDisplayBounds( Rect bounds ) { + if ( mNaviOverlayHelper != null ) { + mNaviOverlayHelper.setCalculatePathDisplayBounds( bounds ); + } + } + + public void displayOverview( Rect bounds ) { + if ( mNaviOverlayHelper != null ) { + mNaviOverlayHelper.displayOverview( bounds ); + } + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/NaviOverlayHelper.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/NaviOverlayHelper.java new file mode 100644 index 0000000000..c057446979 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/NaviOverlayHelper.java @@ -0,0 +1,462 @@ +package com.mogo.map.impl.amap.navi; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Rect; +import android.text.TextUtils; + +import com.amap.api.maps.AMap; +import com.amap.api.maps.CameraUpdateFactory; +import com.amap.api.maps.model.BitmapDescriptorFactory; +import com.amap.api.maps.model.LatLng; +import com.amap.api.maps.model.LatLngBounds; +import com.amap.api.maps.model.Marker; +import com.amap.api.maps.model.MarkerOptions; +import com.amap.api.maps.model.Polyline; +import com.amap.api.navi.AMapNavi; +import com.amap.api.navi.model.AMapNaviLocation; +import com.amap.api.navi.model.AMapNaviPath; +import com.amap.api.navi.model.NaviInfo; +import com.amap.api.navi.model.NaviLatLng; +import com.mogo.map.MogoLatLng; +import com.mogo.map.impl.amap.AMapWrapper; +import com.mogo.map.impl.amap.R; +import com.mogo.map.impl.amap.overlay.RouteOverLayWrapper; +import com.mogo.map.marker.MogoMarkersHandler; +import com.mogo.map.navi.MogoCalculatePath; +import com.mogo.map.navi.OnCalculatePathItemClickInteraction; +import com.mogo.utils.WindowUtils; +import com.mogo.utils.logger.Logger; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * @author congtaowang + * @since 2019-12-27 + *

+ * 导航路径管理 + */ +public class NaviOverlayHelper implements OnCalculatePathItemClickInteraction { + + private static final String TAG = "NaviOverlayHelper"; + + /** + * 选中的路径透明度 + */ + public static final float AMAP_ROUTE_OVERLAY_TRANSPARENCY_SELECTED = 1f; + + /** + * 未选中的路径透明度 + */ + public static final float AMAP_ROUTE_OVERLAY_TRANSPARENCY_UNSELECTED = 0.3f; + + private AMapNavi mAMapNavi; + private AMap mAMap; + private Context mContext; + // 规划的路线显示边距 + private Rect mBoundRect = null; + + private List< CalculatePathItem > mCalculatePathItems; + private List< MogoCalculatePath > mPaths = new ArrayList<>(); + + private int mSelectedPathId; + private CalculatePathItem mSelectedCalculatePathItem; + private OnCalculatePathItemClickInteraction mLineClickInteraction; + + /** + * 起点终点marker + */ + private List< Marker > mMarkers = new ArrayList<>(); + + public NaviOverlayHelper( AMapNavi mAMapNavi, AMap mAMap, Context mContext ) { + this.mAMapNavi = mAMapNavi; + this.mAMap = mAMap; + this.mContext = mContext; + calculateBoundArea(); + } + + /** + * 显示规划的路径 + */ + public void showCalculatedPaths( Runnable after ) { + clearCalculatedOverlay(); + mCalculatePathItems = getSortedPaths(); + if ( mCalculatePathItems == null || mCalculatePathItems.isEmpty() ) { + return; + } + showPathsBound( getBounds(), () -> { + addEndPoints(); + renderPathOverlay( mCalculatePathItems ); + if ( after != null ) { + after.run(); + } + }, mBoundRect ); + } + + private LatLngBounds getBounds() { + if ( mCalculatePathItems == null ) { + return null; + } + LatLngBounds.Builder builder = new LatLngBounds.Builder(); + for ( CalculatePathItem calculatePathItem : mCalculatePathItems ) { + if ( calculatePathItem == null ) { + continue; + } + try { + LatLngBounds bounds = calculatePathItem.getPath().getBoundsForPath(); + builder.include( bounds.northeast ); + builder.include( bounds.southwest ); + } catch ( Exception e ) { + e.printStackTrace(); + } + } + return builder.build(); + } + + /** + * 按pathId升序排序 + * + * @return 排序好的路径规划列表 + */ + private List< CalculatePathItem > getSortedPaths() { + checkAMapInstance(); + final Map< Integer, AMapNaviPath > pathMap = mAMapNavi.getNaviPaths(); + if ( pathMap == null || pathMap.isEmpty() ) { + return null; + } + TreeMap< Integer, AMapNaviPath > sortedMap = + new TreeMap< Integer, AMapNaviPath >( new Comparator< Integer >() { + @Override + public int compare( Integer obj1, Integer obj2 ) { + if ( obj1 != null ) { + return obj1.compareTo( obj2 ); + } + if ( obj2 != null ) { + return obj2.compareTo( obj1 ); + } + return 0; + } + } ); + sortedMap.putAll( pathMap ); + + final List< CalculatePathItem > items = new ArrayList<>(); + for ( Map.Entry< Integer, AMapNaviPath > entry : sortedMap.entrySet() ) { + if ( entry == null || entry.getKey() == null || entry.getValue() == null ) { + continue; + } + items.add( new CalculatePathItem( mContext, mAMap, entry.getKey(), entry.getValue() ) ); + } + return items; + } + + private void calculateBoundArea() { + if ( mBoundRect == null ) { + mBoundRect = new Rect(); + final int padding = WindowUtils.dip2px( mContext, 80 ); + mBoundRect.left = padding; + mBoundRect.right = padding; + mBoundRect.top = padding; + mBoundRect.bottom = padding; + } + } + + public void showBoundsWithSettingBounds() { + showBounds( mBoundRect ); + } + + public void showBounds( Rect bounds ) { + Logger.d( TAG, "showBounds" ); + showPathsBound( getBounds(), null, bounds ); + } + + /** + * 将规划好的路径显示在视野内 + */ + private void showPathsBound( LatLngBounds bounds, Runnable after, Rect rect ) { + if ( bounds == null ) { + return; + } + if ( rect == null ) { + rect = new Rect(); + } + checkAMapInstance(); + mAMap.moveCamera( CameraUpdateFactory.newLatLngBoundsRect( + bounds, + rect.left, + rect.right, + rect.top, + rect.bottom ) ); + if ( after != null ) { + after.run(); + } + } + + private void checkAMapInstance() { + if ( mAMap == null ) { + mAMap = AMapWrapper.getAMap(); + } + } + + public void renderPathOverlay( List< CalculatePathItem > paths ) { + if ( paths == null || paths.size() == 0 ) { + return; + } + for ( int i = 0; i < paths.size(); i++ ) { + final CalculatePathItem item = paths.get( i ); + if ( item == null || item.getPath() == null ) { + continue; + } + RouteOverLayWrapper wrapper = item.getOverLazWrapper( true ); + wrapper.setTrafficLightsVisible( false ); + // 默认选中第一个 + if ( i == 0 ) { + mSelectedPathId = item.getId(); + mSelectedCalculatePathItem = item; + //wrapper.setStartBitmap( R.drawable.ic_navi_start ) + // .setEndBitmap( R.drawable.ic_navi_target ); + mAMapNavi.selectRouteId( item.getId() ); + Logger.d( TAG, "renderPathOverlay set default path" ); + } + wrapper.addToMap(); + wrapper.setTransparency( i == 0 ? AMAP_ROUTE_OVERLAY_TRANSPARENCY_SELECTED : AMAP_ROUTE_OVERLAY_TRANSPARENCY_UNSELECTED ); + } + } + + public void addEndPoints() { + if ( mCalculatePathItems == null || mCalculatePathItems.isEmpty() ) { + return; + } + + Bitmap bitmap = BitmapFactory.decodeResource( mContext.getResources(), R.drawable.ic_endpoint ); + Bitmap startBitmap = BitmapFactory.decodeResource( mContext.getResources(), R.drawable.ic_navi_start ); + Bitmap endBitmap = BitmapFactory.decodeResource( mContext.getResources(), R.drawable.ic_navi_target ); + MarkerOptions options = new MarkerOptions().icon( BitmapDescriptorFactory.fromBitmap( bitmap ) ).zIndex( 0 ).anchor( 0.5f, 0.5f ); + MarkerOptions startOptions = new MarkerOptions().icon( BitmapDescriptorFactory.fromBitmap( startBitmap ) ).zIndex( 0 ).anchor( 0.5f, 1 ); + MarkerOptions endOptions = new MarkerOptions().icon( BitmapDescriptorFactory.fromBitmap( endBitmap ) ).zIndex( 0 ).anchor( 0.5f, 1 ); + for ( CalculatePathItem path : mCalculatePathItems ) { + List< MogoLatLng > points = path.getCoordList(); + if ( points == null || points.isEmpty() ) { + continue; + } + MogoLatLng startPoint = path.getDriveStartPoint(); + MogoLatLng endPoint = path.getDriveEndPoint(); + if ( startPoint == null || endPoint == null ) { + continue; + } + mMarkers.add( mAMap.addMarker( options.position( new LatLng( startPoint.lat, startPoint.lng ) ) ) ); + mMarkers.add( mAMap.addMarker( options.position( new LatLng( endPoint.lat, endPoint.lng ) ) ) ); + mMarkers.add( mAMap.addMarker( startOptions.position( new LatLng( startPoint.lat, startPoint.lng ) ) ) ); + mMarkers.add( mAMap.addMarker( endOptions.position( new LatLng( endPoint.lat, endPoint.lng ) ) ) ); + + break; + } + } + + public void clearCalculatedOverlay() { + if ( mCalculatePathItems != null && !mCalculatePathItems.isEmpty() ) { + for ( CalculatePathItem calculatePathItem : mCalculatePathItems ) { + if ( calculatePathItem == null ) { + continue; + } + RouteOverLayWrapper wrapper = calculatePathItem.getOverLazWrapper( false ); + if ( wrapper != null ) { + wrapper.destroy(); + } + calculatePathItem.release(); + } + mCalculatePathItems.clear(); + } + if ( mPaths != null ) { + mPaths.clear(); + } + if ( !mMarkers.isEmpty() ) { + for ( Marker mMarker : mMarkers ) { + if ( mMarker == null ) { + continue; + } + try { + mMarker.remove(); + mMarker.destroy(); + } catch ( Exception e ) { + + } + } + } + MogoMarkersHandler.getInstance().remove( TAG ); + } + + /** + * 是否切换成功 + * + * @param polyline 选中的线 + */ + public boolean handleClickedPolyline( Polyline polyline, boolean isNaviing ) { + if ( polyline == null ) { + return false; + } + if ( mPaths != null && !mPaths.isEmpty() ) { + for ( MogoCalculatePath path : mPaths ) { + if ( TextUtils.equals( path.getTagId(), polyline.getId() ) ) { + if ( mLineClickInteraction != null ) { + mLineClickInteraction.onItemClicked( path.getTagId() ); + break; + } + } + } + } + return handleClickedPolyline( polyline.getId() ); + } + + private boolean handleClickedPolyline( String id ) { + if ( id == null ) { + return false; + } + Logger.i( TAG, "polyline id = " + id ); + mSelectedCalculatePathItem = isCalculatePolyline( id ); + if ( mSelectedCalculatePathItem == null ) { + return false; + } + mSelectedPathId = mSelectedCalculatePathItem.getId(); + if ( mCalculatePathItems != null ) { + for ( CalculatePathItem item : mCalculatePathItems ) { + final RouteOverLayWrapper wrapper = item.getOverLazWrapper( false ); + if ( wrapper == null ) { + continue; + } + wrapper.setTransparency( + item == mSelectedCalculatePathItem + ? AMAP_ROUTE_OVERLAY_TRANSPARENCY_SELECTED + : AMAP_ROUTE_OVERLAY_TRANSPARENCY_UNSELECTED + ); + } + } + return true; + } + + private CalculatePathItem isCalculatePolyline( String id ) { + CalculatePathItem result = null; + if ( mCalculatePathItems == null || mCalculatePathItems.isEmpty() ) { + return result; + } + for ( CalculatePathItem calculatePathItem : mCalculatePathItems ) { + if ( calculatePathItem == null ) { + continue; + } + final RouteOverLayWrapper wrapper = calculatePathItem.getOverLazWrapper( false ); + if ( wrapper == null ) { + continue; + } + if ( wrapper.getTrafficColorfulPolyline() == null ) { + continue; + } + if ( TextUtils.equals( wrapper.getTrafficColorfulPolyline().getId(), id ) ) { + result = calculatePathItem; + } + } + return result; + } + + public int getSelectedPathId() { + return mSelectedPathId; + } + + /** + * 车辆拐弯时绘制转向箭头 + */ + public void handleNaviInfoUpdate( NaviInfo naviInfo ) { + if ( mSelectedCalculatePathItem != null ) { + RouteOverLayWrapper wrapper = mSelectedCalculatePathItem.getOverLazWrapper( false ); + if ( wrapper != null ) { + wrapper.drawArrow( naviInfo ); + } + } + } + + public void handlePassedLocation( AMapNaviLocation location ) { + if ( mSelectedCalculatePathItem != null ) { + RouteOverLayWrapper wrapper = mSelectedCalculatePathItem.getOverLazWrapper( false ); + if ( wrapper != null ) { + wrapper.updatePolyline( location ); + } + } + } + + public List< MogoCalculatePath > getCalculateStrategies() { + if ( mCalculatePathItems != null && !mCalculatePathItems.isEmpty() ) { + for ( CalculatePathItem calculatePathItem : mCalculatePathItems ) { + MogoCalculatePath path = new MogoCalculatePath(); + path.setFormattedDistance( calculatePathItem.getFormattedDistance() ); + path.setPathId( calculatePathItem.getId() ); + path.setStrategyName( calculatePathItem.getStrategyName() ); + path.setFormattedTime( calculatePathItem.getFormattedTime() ); + path.setTime( calculatePathItem.getTime() ); + path.setDistance( calculatePathItem.getDistance() ); + List< NaviLatLng > coordList = calculatePathItem.getPath().getCoordList(); + ArrayList< MogoLatLng > mogoLatLngs = new ArrayList<>(); + for ( NaviLatLng latlng : coordList + ) { + MogoLatLng mogoLatLng = + new MogoLatLng( latlng.getLatitude(), latlng.getLongitude() ); + mogoLatLngs.add( mogoLatLng ); + } + path.setCoordList( mogoLatLngs ); + path.setTrafficLights( calculatePathItem.getTrafficNumber() ); + mPaths.add( path ); + final RouteOverLayWrapper wrapper = calculatePathItem.getOverLazWrapper( true ); + if ( wrapper == null ) { + continue; + } + if ( wrapper.getTrafficColorfulPolyline() == null ) { + continue; + } + path.setTagId( wrapper.getTrafficColorfulPolyline().getId() ); + } + } + + return mPaths; + } + + public List< MogoLatLng > getCalculatedPathPos() { + + if ( mSelectedCalculatePathItem != null ) { + return mSelectedCalculatePathItem.getCoordList(); + } + //if (mPaths != null && !mPaths.isEmpty()) { + // return mPaths.get(0).getCoordList(); + //} + return null; + } + + @Override + public void onItemClicked( String tagId ) { + handleClickedPolyline( tagId ); + mAMapNavi.selectRouteId( getSelectedPathId() ); + showBounds( mBoundRect ); + } + + public OnCalculatePathItemClickInteraction getItemClickInteraction() { + return this; + } + + public void setLineClickInteraction( OnCalculatePathItemClickInteraction lineClickInteraction ) { + mLineClickInteraction = lineClickInteraction; + } + + public void setCalculatePathDisplayBounds( Rect bounds ) { + if ( bounds != null ) { + mBoundRect = bounds; + } + } + + /** + * 展示全程 + */ + public void displayOverview( Rect bounds ) { + showBounds( bounds ); + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/PathPlanningErrorCodeConstants.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/PathPlanningErrorCodeConstants.java new file mode 100644 index 0000000000..7404d6049d --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/PathPlanningErrorCodeConstants.java @@ -0,0 +1,92 @@ +package com.mogo.map.impl.amap.navi; + +import com.amap.api.navi.enums.PathPlanningErrCode; + +/** + * @author congtaowang + * @since 2019-10-18 + *

+ * 描述 + */ +public enum PathPlanningErrorCodeConstants { + + NONE( -1, "路线规划错误,请重试" ), + + ACCESS_TOO_FREQUENT( PathPlanningErrCode.ACCESS_TOO_FREQUENT, "访问过于频繁,请稍后再试" ), + + DISABLE_RESTRICT( PathPlanningErrCode.DISABLE_RESTRICT, "无法躲避限行区域,请重新规划" ), + + ERROR_BUF( PathPlanningErrCode.ERROR_BUF, "Buf数据格式错误" ), + + ERROR_CONNECTION( PathPlanningErrCode.ERROR_CONNECTION, "网络超时或网络失败。" ), + + ERROR_DISTANCE( PathPlanningErrCode.ERROR_DISTANCE, "起点/终点/途经点的距离太长(步行距离>100km,骑行距离>1200km)" ), + + ERROR_ENCODER( PathPlanningErrCode.ERROR_ENCODER, "算路服务端编码失败" ), + + ERROR_ENDPOINT( PathPlanningErrCode.ERROR_ENDPOINT, "终点错误" ), + + ERROR_NAVI_PARAMS( PathPlanningErrCode.ERROR_NAVI_PARAMS, "调用直接导航 没有算路 参数错误,缺失有效的导航路径,无法开始导航" ), + + ERROR_NOROADFORENDPOINT( PathPlanningErrCode.ERROR_NOROADFORENDPOINT, "终点没有找到道路" ), + + ERROR_NOROADFORSTARTPOINT( PathPlanningErrCode.ERROR_NOROADFORSTARTPOINT, "起点没有找到道路。" ), + + ERROR_NOROADFORWAYPOINT( PathPlanningErrCode.ERROR_NOROADFORWAYPOINT, "途径点没有找到道路" ), + + ERROR_PREVIEW( PathPlanningErrCode.ERROR_PREVIEW, "路径数据缺乏预览数据" ), + + ERROR_PROTOCOL( PathPlanningErrCode.ERROR_PROTOCOL, "请求协议非法。" ), + + ERROR_STARTPOINT( PathPlanningErrCode.ERROR_STARTPOINT, "起点错误" ), + + ERROR_WAYPOINT( PathPlanningErrCode.ERROR_WAYPOINT, "途经点错误" ), + + INSUFFICIENT_PRIVILEGES( PathPlanningErrCode.INSUFFICIENT_PRIVILEGES, "无权限访问此服务。" ), + + INVALID_PARAMS( PathPlanningErrCode.INVALID_PARAMS, "请求参数非法。" ), + + INVALID_USER_KEY( PathPlanningErrCode.INVALID_USER_KEY, "用户key非法或过期(请检查key是否正确)" ), + + INVALID_USER_SCODE( PathPlanningErrCode.INVALID_USER_SCODE, "MD5安全码未通过验证,需要开发者判定key绑定的SHA1,package是否与sdk包里的一致." ), + + OUT_OF_SERVICE( PathPlanningErrCode.OUT_OF_SERVICE, "使用路径规划服务接口时可能出现该问题,规划点(包括起点、终点、途经点)不在中国陆地范围内" ), + + OVER_DIRECTION_RANGE( PathPlanningErrCode.OVER_DIRECTION_RANGE, "使用路径规划服务接口时可能出现该问题,路线计算失败,通常是由于道路起点和终点距离过长导致" ), + + OVER_QUOTA( PathPlanningErrCode.OVER_QUOTA, "请求超出配额。" ), + + SERVICE_NOT_EXIST( PathPlanningErrCode.SERVICE_NOT_EXIST, "请求服务不存在。" ), + + SERVICE_RESPONSE_ERROR( PathPlanningErrCode.SERVICE_RESPONSE_ERROR, "请求服务响应错误。" ), + + UNKNOWN_ERROR( PathPlanningErrCode.UNKNOWN_ERROR, "未知错误(可能是由于连接的网络无法访问外网)" ), + + USERKEY_PLAT_NOMATCH( PathPlanningErrCode.USERKEY_PLAT_NOMATCH, "请求中使用的key与绑定平台不符,例如:开发者申请的是js api的key,却用来调web服务接口" ); + + private int code; + private String errorMsg; + + PathPlanningErrorCodeConstants( int code, String errorMsg ) { + this.code = code; + this.errorMsg = errorMsg; + } + + public int getCode() { + return code; + } + + public String getErrorMsg() { + return errorMsg; + } + + public static String getErrorMsg( int code ) { + for ( PathPlanningErrorCodeConstants value : PathPlanningErrorCodeConstants.values() ) { + if ( value.getCode() == code ) { + return value.getErrorMsg(); + } + } + return NONE.getErrorMsg(); + } + +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/TTSSpeaker.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/TTSSpeaker.java new file mode 100644 index 0000000000..dd5c6ec2f6 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/navi/TTSSpeaker.java @@ -0,0 +1,120 @@ +package com.mogo.map.impl.amap.navi; + +import android.text.TextUtils; + +import com.mogo.commons.AbsMogoApplication; +import com.mogo.commons.voice.AIAssist; +import com.mogo.commons.voice.IMogoVoiceCmdCallBack; + +import java.util.LinkedList; + +/** + * @author congtaowang + * @since 2020-04-21 + *

+ * 播报导航TTS + *

+ * 策略:队列缓存预播报的 tts,然后上一句播完后 + */ +public class TTSSpeaker implements IMogoVoiceCmdCallBack { + + private static volatile TTSSpeaker sInstance; + + private TTSSpeaker() { + } + + public static TTSSpeaker getInstance() { + if ( sInstance == null ) { + synchronized ( TTSSpeaker.class ) { + if ( sInstance == null ) { + sInstance = new TTSSpeaker(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + private LinkedList< String > mWaiting = new LinkedList<>(); + + private String mLastTts = null; + private String mLastTtsId = null; + + public synchronized void speakTTS( String tts ) { + if ( TextUtils.isEmpty( tts ) ) { + return; + } + mWaiting.add( tts ); + peekAndSpeak(); + } + + public synchronized void shutUp() { + if ( mLastTtsId != null ) { + AIAssist.getInstance( AbsMogoApplication.getApp() ).shutUp( mLastTtsId, mLastTts ); + mWaiting.clear(); + mLastTtsId = null; + mLastTts = null; + } + } + + @Override + public void onCmdSelected( String cmd ) { + + } + + @Override + public void onCmdAction( String speakText ) { + + } + + @Override + public void onCmdCancel( String speakText ) { + + } + + @Override + public void onSpeakEnd( String speakText ) { + + } + + @Override + public void onSpeakSelectTimeOut( String speakText ) { + + } + + @Override + public void onTTSStart( String ttsId, String tts ) { + if ( TextUtils.equals( mLastTts, tts ) ) { + mLastTtsId = ttsId; + } + } + + @Override + public void onTTSEnd( String ttsId, String tts ) { + mLastTtsId = null; + peekAndSpeak(); + } + + @Override + public void onTTSError( String ttsId, String tts ) { + mLastTtsId = null; + peekAndSpeak(); + } + + private synchronized void peekAndSpeak() { + if ( mWaiting.isEmpty() ) { + mLastTts = null; + mLastTtsId = null; + return; + } + if ( mLastTtsId != null ) { + // 上一句还没有播完 + return; + } + mLastTts = mWaiting.pop(); + AIAssist.getInstance( AbsMogoApplication.getApp() ).speakTTSAndDuck( mLastTts, this ); + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/AMapPolylineWrapper.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/AMapPolylineWrapper.java new file mode 100644 index 0000000000..0c2766d842 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/AMapPolylineWrapper.java @@ -0,0 +1,196 @@ +package com.mogo.map.impl.amap.overlay; + +import com.amap.api.maps.model.LatLng; +import com.amap.api.maps.model.Polyline; +import com.amap.api.maps.model.PolylineOptions; +import com.mogo.map.MogoLatLng; +import com.mogo.map.impl.amap.utils.ObjectUtils; +import com.mogo.map.overlay.IMogoPolyline; +import com.mogo.map.overlay.MogoPolylineOptions; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author congtaowang + * @since 2020-03-10 + *

+ * 描述 + */ +public class AMapPolylineWrapper implements IMogoPolyline { + + private Polyline mPolyline; + private MogoPolylineOptions mOptions; + private boolean mIsDestroyed = false; + + public AMapPolylineWrapper( Polyline mPolyline, + MogoPolylineOptions mOptions ) { + this.mPolyline = mPolyline; + this.mOptions = mOptions; + } + + @Override + public void destroy() { + remove(); + } + + @Override + public void remove() { + if ( mPolyline != null ) { + mPolyline.remove(); + } + mIsDestroyed = true; + } + + @Override + public String getId() { + if ( mPolyline != null ) { + return mPolyline.getId(); + } + return null; + } + + @Override + public void setPoints( List< MogoLatLng > lonLats ) { + if ( lonLats == null || lonLats.isEmpty() ) { + mPolyline.setPoints( new ArrayList< LatLng >() ); + return; + } + ArrayList< LatLng > points = new ArrayList<>(); + for ( MogoLatLng lonLat : lonLats ) { + LatLng latLng = ObjectUtils.fromMogo2( lonLat ); + if ( latLng == null ) { + continue; + } + points.add( latLng ); + } + mPolyline.setPoints( points ); + } + + @Override + public List< MogoLatLng > getPoints() { + if ( mPolyline == null ) { + return null; + } + ArrayList< MogoLatLng > lonLats = new ArrayList<>(); + List< LatLng > points = mPolyline.getPoints(); + if ( points != null ) { + for ( LatLng latLng : points ) { + MogoLatLng lonLat = ObjectUtils.fromAMap( latLng ); + if ( lonLat == null ) { + continue; + } + lonLats.add( lonLat ); + } + } + return lonLats; + } + + @Override + public void setGeodesic( boolean draw ) { + if ( mPolyline != null ) { + mPolyline.setGeodesic( draw ); + } + } + + @Override + public boolean isGeodesic() { + return mPolyline == null ? false : mPolyline.isGeodesic(); + } + + @Override + public void setDottedLine( boolean dottedLine ) { + if ( mPolyline != null ) { + mPolyline.setDottedLine( dottedLine ); + } + } + + @Override + public boolean isDottedLine() { + return mPolyline == null ? false : mPolyline.isDottedLine(); + } + + @Override + public void setWidth( float width ) { + if ( mPolyline != null ) { + mPolyline.setWidth( width ); + } + } + + @Override + public float getWidth() { + if ( mPolyline != null ) { + return mPolyline.getWidth(); + } + return 0; + } + + @Override + public void setColor( int color ) { + if ( mPolyline != null ) { + mPolyline.setColor( color ); + } + } + + @Override + public int getColor() { + if ( mPolyline != null ) { + return mPolyline.getColor(); + } + return 0; + } + + @Override + public void setZIndex( float zIndex ) { + if ( mPolyline != null ) { + mPolyline.setZIndex( zIndex ); + } + } + + @Override + public float getZIndex() { + if ( mPolyline != null ) { + return mPolyline.getZIndex(); + } + return 0; + } + + @Override + public void setVisible( boolean visible ) { + if ( mPolyline != null ) { + mPolyline.setVisible( visible ); + } + } + + @Override + public boolean isVisible() { + if ( mPolyline != null ) { + return mPolyline.isVisible(); + } + return false; + } + + @Override + public void setTransparency( float transparency ) { + if ( mPolyline != null ) { + mPolyline.setTransparency( transparency ); + } + } + + @Override + public void setOption( MogoPolylineOptions option ) { + PolylineOptions target = ObjectUtils.fromMogo( option ); + if ( target == null ) { + return; + } + mOptions = option; + if ( mPolyline != null ) { + mPolyline.setOptions( target ); + } + } + + @Override + public boolean isDestroyed() { + return false; + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/AMapUtil.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/AMapUtil.java new file mode 100755 index 0000000000..a7a6f8eabd --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/AMapUtil.java @@ -0,0 +1,268 @@ +package com.mogo.map.impl.amap.overlay; + +import android.text.Html; +import android.text.Spanned; +import android.widget.EditText; + +import com.amap.api.maps.model.LatLng; +import com.amap.api.services.core.LatLonPoint; +import com.amap.api.services.route.BusPath; +import com.amap.api.services.route.BusStep; +import com.amap.api.services.route.RouteBusLineItem; +import com.amap.api.services.route.RouteRailwayItem; +import com.mogo.map.impl.amap.R; + +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class AMapUtil { + /** + * 判断edittext是否null + */ + public static String checkEditText(EditText editText) { + if (editText != null && editText.getText() != null + && !(editText.getText().toString().trim().equals(""))) { + return editText.getText().toString().trim(); + } else { + return ""; + } + } + + public static Spanned stringToSpan(String src) { + return src == null ? null : Html.fromHtml(src.replace("\n", "
")); + } + + public static String colorFont(String src, String color) { + StringBuffer strBuf = new StringBuffer(); + + strBuf.append("").append(src) + .append(""); + return strBuf.toString(); + } + + public static String makeHtmlNewLine() { + return "
"; + } + + public static String makeHtmlSpace(int number) { + final String space = " "; + StringBuilder result = new StringBuilder(); + for (int i = 0; i < number; i++) { + result.append(space); + } + return result.toString(); + } + + public static String getFriendlyLength(int lenMeter) { + if (lenMeter > 10000) // 10 km + { + int dis = lenMeter / 1000; + return dis + ChString.Kilometer; + } + + if (lenMeter > 1000) { + float dis = (float) lenMeter / 1000; + DecimalFormat fnum = new DecimalFormat("##0.0"); + String dstr = fnum.format(dis); + return dstr + ChString.Kilometer; + } + + if (lenMeter > 100) { + int dis = lenMeter / 50 * 50; + return dis + ChString.Meter; + } + + int dis = lenMeter / 10 * 10; + if (dis == 0) { + dis = 10; + } + + return dis + ChString.Meter; + } + + public static boolean IsEmptyOrNullString(String s) { + return (s == null) || (s.trim().length() == 0); + } + + /** + * 把LatLng对象转化为LatLonPoint对象 + */ + public static LatLonPoint convertToLatLonPoint(LatLng latlon) { + return new LatLonPoint(latlon.latitude, latlon.longitude); + } + + /** + * 把LatLonPoint对象转化为LatLon对象 + */ + public static LatLng convertToLatLng(LatLonPoint latLonPoint) { + return new LatLng(latLonPoint.getLatitude(), latLonPoint.getLongitude()); + } + + /** + * 把集合体的LatLonPoint转化为集合体的LatLng + */ + public static ArrayList convertArrList(List shapes) { + ArrayList lineShapes = new ArrayList(); + for (LatLonPoint point : shapes) { + LatLng latLngTemp = AMapUtil.convertToLatLng(point); + lineShapes.add(latLngTemp); + } + return lineShapes; + } + + /** + * long类型时间格式化 + */ + public static String convertToTime(long time) { + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = new Date(time); + return df.format(date); + } + + public static final String HtmlBlack = "#000000"; + public static final String HtmlGray = "#808080"; + + public static String getFriendlyTime(int second) { + if (second > 3600) { + int hour = second / 3600; + int miniate = (second % 3600) / 60; + return hour + "小时" + miniate + "分钟"; + } + if (second >= 60) { + int miniate = second / 60; + return miniate + "分钟"; + } + return second + "秒"; + } + + //路径规划方向指示和图片对应 + public static int getDriveActionID(String actionName) { + if (actionName == null || actionName.equals("")) { + return R.drawable.dir3; + } + if ("左转".equals(actionName)) { + return R.drawable.dir2; + } + if ("右转".equals(actionName)) { + return R.drawable.dir1; + } + if ("向左前方行驶".equals(actionName) || "靠左".equals(actionName)) { + return R.drawable.dir6; + } + if ("向右前方行驶".equals(actionName) || "靠右".equals(actionName)) { + return R.drawable.dir5; + } + if ("向左后方行驶".equals(actionName) || "左转调头".equals(actionName)) { + return R.drawable.dir7; + } + if ("向右后方行驶".equals(actionName)) { + return R.drawable.dir8; + } + if ("直行".equals(actionName)) { + return R.drawable.dir3; + } + if ("减速行驶".equals(actionName)) { + return R.drawable.dir4; + } + return R.drawable.dir3; + } + + public static int getWalkActionID(String actionName) { + if (actionName == null || actionName.equals("")) { + return R.drawable.dir13; + } + if ("左转".equals(actionName)) { + return R.drawable.dir2; + } + if ("右转".equals(actionName)) { + return R.drawable.dir1; + } + if ("向左前方".equals(actionName) || "靠左".equals(actionName) || actionName.contains("向左前方")) { + return R.drawable.dir6; + } + if ("向右前方".equals(actionName) || "靠右".equals(actionName) || actionName.contains("向右前方")) { + return R.drawable.dir5; + } + if ("向左后方".equals(actionName) || actionName.contains("向左后方")) { + return R.drawable.dir7; + } + if ("向右后方".equals(actionName) || actionName.contains("向右后方")) { + return R.drawable.dir8; + } + if ("直行".equals(actionName)) { + return R.drawable.dir3; + } + if ("通过人行横道".equals(actionName)) { + return R.drawable.dir9; + } + if ("通过过街天桥".equals(actionName)) { + return R.drawable.dir11; + } + if ("通过地下通道".equals(actionName)) { + return R.drawable.dir10; + } + + return R.drawable.dir13; + } + + public static String getBusPathTitle(BusPath busPath) { + if (busPath == null) { + return String.valueOf(""); + } + List busSetps = busPath.getSteps(); + if (busSetps == null) { + return String.valueOf(""); + } + StringBuffer sb = new StringBuffer(); + for (BusStep busStep : busSetps) { + StringBuffer title = new StringBuffer(); + if (busStep.getBusLines().size() > 0) { + for (RouteBusLineItem busline : busStep.getBusLines()) { + if (busline == null) { + continue; + } + + String buslineName = getSimpleBusLineName(busline.getBusLineName()); + title.append(buslineName); + title.append(" / "); + } +// RouteBusLineItem busline = busStep.getBusLines().get(0); + + sb.append(title.substring(0, title.length() - 3)); + sb.append(" > "); + } + if (busStep.getRailway() != null) { + RouteRailwayItem railway = busStep.getRailway(); + sb.append(railway.getTrip() + "(" + railway.getDeparturestop().getName() + + " - " + railway.getArrivalstop().getName() + ")"); + sb.append(" > "); + } + } + return sb.substring(0, sb.length() - 3); + } + + public static String getBusPathDes(BusPath busPath) { + if (busPath == null) { + return String.valueOf(""); + } + long second = busPath.getDuration(); + String time = getFriendlyTime((int) second); + float subDistance = busPath.getDistance(); + String subDis = getFriendlyLength((int) subDistance); + float walkDistance = busPath.getWalkDistance(); + String walkDis = getFriendlyLength((int) walkDistance); + return String.valueOf(time + " | " + subDis + " | 步行" + walkDis); + } + + public static String getSimpleBusLineName(String busLineName) { + if (busLineName == null) { + return String.valueOf(""); + } + return busLineName.replaceAll("\\(.*?\\)", ""); + } + + +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/ChString.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/ChString.java new file mode 100755 index 0000000000..2368d553ca --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/ChString.java @@ -0,0 +1,26 @@ +package com.mogo.map.impl.amap.overlay; + +public class ChString { + public static final String Kilometer = "\u516c\u91cc";// "公里"; + public static final String Meter = "\u7c73";// "米"; + public static final String ByFoot = "\u6b65\u884c";// "步行"; + public static final String To = "\u53bb\u5f80";// "去往"; + public static final String Station = "\u8f66\u7ad9";// "车站"; + public static final String TargetPlace = "\u76ee\u7684\u5730";// "目的地"; + public static final String StartPlace = "\u51fa\u53d1\u5730";// "出发地"; + public static final String About = "\u5927\u7ea6";// "大约"; + public static final String Direction = "\u65b9\u5411";// "方向"; + + public static final String GetOn = "\u4e0a\u8f66";// "上车"; + public static final String GetOff = "\u4e0b\u8f66";// "下车"; + public static final String Zhan = "\u7ad9";// "站"; + + public static final String cross = "\u4ea4\u53c9\u8def\u53e3"; // 交叉路口 + public static final String type = "\u7c7b\u522b"; // 类别 + public static final String address = "\u5730\u5740"; // 地址 + public static final String PrevStep = "\u4e0a\u4e00\u6b65"; + public static final String NextStep = "\u4e0b\u4e00\u6b65"; + public static final String Gong = "\u516c\u4ea4"; + public static final String ByBus = "\u4e58\u8f66"; + public static final String Arrive = "\u5230\u8FBE";// 到达 +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/DrivingRouteOverlay.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/DrivingRouteOverlay.java new file mode 100755 index 0000000000..619962b46a --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/DrivingRouteOverlay.java @@ -0,0 +1,388 @@ +package com.mogo.map.impl.amap.overlay; + +import android.content.Context; +import android.graphics.Color; + +import com.amap.api.maps.AMap; +import com.amap.api.maps.model.BitmapDescriptor; +import com.amap.api.maps.model.BitmapDescriptorFactory; +import com.amap.api.maps.model.LatLng; +import com.amap.api.maps.model.LatLngBounds; +import com.amap.api.maps.model.Marker; +import com.amap.api.maps.model.MarkerOptions; +import com.amap.api.maps.model.PolylineOptions; +import com.amap.api.services.core.LatLonPoint; +import com.amap.api.services.route.DrivePath; +import com.amap.api.services.route.DriveStep; +import com.amap.api.services.route.TMC; +import com.mogo.map.impl.amap.R; + +import java.util.ArrayList; +import java.util.List; + + +/** + * 导航路线图层类 + */ +public class DrivingRouteOverlay extends RouteOverlay { + private DrivePath drivePath; + private List throughPointList; + private List throughPointMarkerList = new ArrayList(); + private boolean throughPointMarkerVisible = true; + private List tmcs; + private PolylineOptions mPolylineOptions; + private PolylineOptions mPolylineOptionscolor; + private Context mContext; + private boolean isColorfulline = true; + private float mWidth = 4; + private List mLatLngsOfPath; + + public void setIsColorfulline(boolean iscolorfulline) { + this.isColorfulline = iscolorfulline; + } + + /** + * 根据给定的参数,构造一个导航路线图层类对象。 + * + * @param amap 地图对象。 + * @param path 导航路线规划方案。 + * @param context 当前的activity对象。 + */ + public DrivingRouteOverlay(Context context, + AMap amap, + DrivePath path, + LatLonPoint start, + LatLonPoint end, + List throughPointList) { + super(context); + mContext = context; + mAMap = amap; + this.drivePath = path; + startPoint = AMapUtil.convertToLatLng(start); + endPoint = AMapUtil.convertToLatLng(end); + this.throughPointList = throughPointList; + + initBitmapDescriptor(); + } + + public float getRouteWidth() { + return mWidth; + } + + /** + * 设置路线宽度 + * + * @param mWidth 路线宽度,取值范围:大于0 + */ + public void setRouteWidth(float mWidth) { + this.mWidth = mWidth; + } + + /** + * 添加驾车路线添加到地图上显示。 + */ + public void addToMap() { + initPolylineOptions(); + try { + if (mAMap == null) { + return; + } + + if (mWidth == 0 || drivePath == null) { + return; + } + mLatLngsOfPath = new ArrayList(); + tmcs = new ArrayList(); + List drivePaths = drivePath.getSteps(); + mPolylineOptions.add(startPoint); + for (int i = 0; i < drivePaths.size(); i++) { + DriveStep step = drivePaths.get(i); + List latlonPoints = step.getPolyline(); + List tmclist = step.getTMCs(); + tmcs.addAll(tmclist); + addDrivingStationMarkers(step, convertToLatLng(latlonPoints.get(0))); + for (LatLonPoint latlonpoint : latlonPoints) { + mPolylineOptions.add(convertToLatLng(latlonpoint)); + mLatLngsOfPath.add(convertToLatLng(latlonpoint)); + } + } + mPolylineOptions.add(endPoint); + if (startMarker != null) { + startMarker.remove(); + startMarker = null; + } + + if (endMarker != null) { + endMarker.remove(); + endMarker = null; + } +// addStartAndEndMarker(); +// addThroughPointMarker(); + if (isColorfulline && tmcs.size() > 0) { + colorWayUpdate(tmcs); + showcolorPolyline(); + } else { + showPolyline(); + } + + } catch (Throwable e) { + e.printStackTrace(); + } + } + + /** + * 初始化线段属性 + */ + private void initPolylineOptions() { + mPolylineOptions = null; + mPolylineOptions = new PolylineOptions(); + mPolylineOptions.color(getDriveColor()).width(getRouteWidth()); + } + + private void showPolyline() { + addPolyLine(mPolylineOptions); + } + + private void showcolorPolyline() { + addPolyLine(mPolylineOptionscolor); + } + + /** + * 根据不同的路段拥堵情况展示不同的颜色 + * + * @param tmcSection + */ + private void colorWayUpdate(List tmcSection) { + if (mAMap == null) { + return; + } + if (tmcSection == null || tmcSection.size() <= 0) { + return; + } + TMC segmentTrafficStatus; + mPolylineOptionscolor = null; + mPolylineOptionscolor = new PolylineOptions(); + mPolylineOptionscolor.width(getRouteWidth()); + List colorList = new ArrayList(); + List bitmapDescriptors = new ArrayList(); + List points = new ArrayList<>(); + List texIndexList = new ArrayList(); +// mPolylineOptionscolor.add(startPoint); +// mPolylineOptionscolor.add(AMapUtil.convertToLatLng(tmcSection.get(0).getPolyline().get(0))); + + points.add(startPoint); + points.add(AMapUtil.convertToLatLng(tmcSection.get(0).getPolyline().get(0))); + colorList.add(getDriveColor()); + bitmapDescriptors.add(defaultRoute); + + BitmapDescriptor bitmapDescriptor = null; + int textIndex = 0; + texIndexList.add(textIndex); + texIndexList.add(++textIndex); + for (int i = 0; i < tmcSection.size(); i++) { + segmentTrafficStatus = tmcSection.get(i); + int color = getcolor(segmentTrafficStatus.getStatus()); + bitmapDescriptor = getTrafficBitmapDescriptor(segmentTrafficStatus.getStatus()); + List mployline = segmentTrafficStatus.getPolyline(); + for (int j = 0; j < mployline.size(); j++) { +// mPolylineOptionscolor.add(AMapUtil.convertToLatLng(mployline.get(j))); + points.add(AMapUtil.convertToLatLng(mployline.get(j))); + colorList.add(color); + + texIndexList.add(++textIndex); + bitmapDescriptors.add(bitmapDescriptor); + } + } + + points.add(endPoint); + colorList.add(getDriveColor()); + bitmapDescriptors.add(defaultRoute); + texIndexList.add(++textIndex); + mPolylineOptionscolor.addAll(points); + mPolylineOptionscolor.colorValues(colorList); + +// mPolylineOptionscolor.setCustomTextureIndex(texIndexList); +// mPolylineOptionscolor.setCustomTextureList(bitmapDescriptors); + } + + private BitmapDescriptor defaultRoute = null; + private BitmapDescriptor unknownTraffic = null; + private BitmapDescriptor smoothTraffic = null; + private BitmapDescriptor slowTraffic = null; + private BitmapDescriptor jamTraffic = null; + private BitmapDescriptor veryJamTraffic = null; + + private void initBitmapDescriptor() { + defaultRoute = BitmapDescriptorFactory.fromResource( R.drawable.amap_route_color_texture_6_arrow); + smoothTraffic = BitmapDescriptorFactory.fromResource(R.drawable.amap_route_color_texture_4_arrow); + unknownTraffic = BitmapDescriptorFactory.fromResource(R.drawable.amap_route_color_texture_0_arrow); + slowTraffic = BitmapDescriptorFactory.fromResource(R.drawable.amap_route_color_texture_3_arrow); + jamTraffic = BitmapDescriptorFactory.fromResource(R.drawable.amap_route_color_texture_2_arrow); + veryJamTraffic = BitmapDescriptorFactory.fromResource(R.drawable.amap_route_color_texture_9_arrow); + } + + private BitmapDescriptor getTrafficBitmapDescriptor(String status) { + if (status.equals("畅通")) { + return smoothTraffic; + } else if (status.equals("缓行")) { + return slowTraffic; + } else if (status.equals("拥堵")) { + return jamTraffic; + } else if (status.equals("严重拥堵")) { + return veryJamTraffic; + } else { + return defaultRoute; + } + } + + + private int getcolor(String status) { + if (status.equals("畅通")) { + return Color.GREEN; + } else if (status.equals("缓行")) { + return Color.YELLOW; + } else if (status.equals("拥堵")) { + return Color.RED; + } else if (status.equals("严重拥堵")) { + return Color.parseColor("#990033"); + } else { + return Color.GREEN; + } + } + + public LatLng convertToLatLng(LatLonPoint point) { + return new LatLng(point.getLatitude(), point.getLongitude()); + } + + /** + * @param driveStep + * @param latLng + */ + private void addDrivingStationMarkers(DriveStep driveStep, LatLng latLng) { + addStationMarker(new MarkerOptions() + .position(latLng) + .title("\u65B9\u5411:" + driveStep.getAction() + + "\n\u9053\u8DEF:" + driveStep.getRoad()) + .snippet(driveStep.getInstruction()).visible(nodeIconVisible) + .anchor(0.5f, 0.5f).icon(getDriveBitmapDescriptor())); + } + + @Override + protected LatLngBounds getLatLngBounds() { + LatLngBounds.Builder b = LatLngBounds.builder(); + b.include(new LatLng(startPoint.latitude, startPoint.longitude)); + b.include(new LatLng(endPoint.latitude, endPoint.longitude)); + if (this.throughPointList != null && this.throughPointList.size() > 0) { + for (int i = 0; i < this.throughPointList.size(); i++) { + b.include(new LatLng( + this.throughPointList.get(i).getLatitude(), + this.throughPointList.get(i).getLongitude())); + } + } + return b.build(); + } + + public void setThroughPointIconVisibility(boolean visible) { + try { + throughPointMarkerVisible = visible; + if (this.throughPointMarkerList != null + && this.throughPointMarkerList.size() > 0) { + for (int i = 0; i < this.throughPointMarkerList.size(); i++) { + this.throughPointMarkerList.get(i).setVisible(visible); + } + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + + private void addThroughPointMarker() { + if (this.throughPointList != null && this.throughPointList.size() > 0) { + LatLonPoint latLonPoint = null; + for (int i = 0; i < this.throughPointList.size(); i++) { + latLonPoint = this.throughPointList.get(i); + if (latLonPoint != null) { + throughPointMarkerList.add(mAMap + .addMarker((new MarkerOptions()) + .position( + new LatLng(latLonPoint + .getLatitude(), latLonPoint + .getLongitude())) + .visible(throughPointMarkerVisible) + .icon(getThroughPointBitDes()) + .title("\u9014\u7ECF\u70B9"))); + } + } + } + } + + private BitmapDescriptor getThroughPointBitDes() { + return BitmapDescriptorFactory.fromResource(R.drawable.amap_through); + + } + + /** + * 获取两点间距离 + * + * @param start + * @param end + * @return + */ + public static int calculateDistance(LatLng start, LatLng end) { + double x1 = start.longitude; + double y1 = start.latitude; + double x2 = end.longitude; + double y2 = end.latitude; + return calculateDistance(x1, y1, x2, y2); + } + + public static int calculateDistance(double x1, double y1, double x2, double y2) { + final double NF_pi = 0.01745329251994329; // 弧度 PI/180 + x1 *= NF_pi; + y1 *= NF_pi; + x2 *= NF_pi; + y2 *= NF_pi; + double sinx1 = Math.sin(x1); + double siny1 = Math.sin(y1); + double cosx1 = Math.cos(x1); + double cosy1 = Math.cos(y1); + double sinx2 = Math.sin(x2); + double siny2 = Math.sin(y2); + double cosx2 = Math.cos(x2); + double cosy2 = Math.cos(y2); + double[] v1 = new double[3]; + v1[0] = cosy1 * cosx1 - cosy2 * cosx2; + v1[1] = cosy1 * sinx1 - cosy2 * sinx2; + v1[2] = siny1 - siny2; + double dist = Math.sqrt(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]); + + return (int) (Math.asin(dist / 2) * 12742001.5798544); + } + + + //获取指定两点之间固定距离点 + public static LatLng getPointForDis(LatLng sPt, LatLng ePt, double dis) { + double lSegLength = calculateDistance(sPt, ePt); + double preResult = dis / lSegLength; + return new LatLng((ePt.latitude - sPt.latitude) * preResult + sPt.latitude, (ePt.longitude - sPt.longitude) * preResult + sPt.longitude); + } + + /** + * 去掉DriveLineOverlay上的线段和标记。 + */ + @Override + public void removeFromMap() { + try { + super.removeFromMap(); + if (this.throughPointMarkerList != null + && this.throughPointMarkerList.size() > 0) { + for (int i = 0; i < this.throughPointMarkerList.size(); i++) { + this.throughPointMarkerList.get(i).remove(); + } + this.throughPointMarkerList.clear(); + } + } catch (Throwable e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/OnRouteSearchListenerAdapter.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/OnRouteSearchListenerAdapter.java new file mode 100644 index 0000000000..c5189413a8 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/OnRouteSearchListenerAdapter.java @@ -0,0 +1,36 @@ +package com.mogo.map.impl.amap.overlay; + +import com.amap.api.services.route.BusRouteResult; +import com.amap.api.services.route.DriveRouteResult; +import com.amap.api.services.route.RideRouteResult; +import com.amap.api.services.route.RouteSearch; +import com.amap.api.services.route.WalkRouteResult; + +/** + * @author congtaowang + * @since 2020-01-08 + *

+ * 描述 + */ +public abstract class OnRouteSearchListenerAdapter implements RouteSearch.OnRouteSearchListener { + + @Override + public void onBusRouteSearched( BusRouteResult busRouteResult, int i ) { + + } + + @Override + public void onDriveRouteSearched( DriveRouteResult driveRouteResult, int i ) { + + } + + @Override + public void onWalkRouteSearched( WalkRouteResult walkRouteResult, int i ) { + + } + + @Override + public void onRideRouteSearched( RideRouteResult rideRouteResult, int i ) { + + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/RouteOverLayWrapper.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/RouteOverLayWrapper.java new file mode 100644 index 0000000000..c5a6857603 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/RouteOverLayWrapper.java @@ -0,0 +1,211 @@ +package com.mogo.map.impl.amap.overlay; + +import android.content.Context; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.util.Log; + +import com.amap.api.maps.AMap; +import com.amap.api.maps.model.NavigateArrowOptions; +import com.amap.api.maps.model.Polyline; +import com.amap.api.navi.model.AMapNaviLocation; +import com.amap.api.navi.model.AMapNaviPath; +import com.amap.api.navi.model.NaviInfo; +import com.amap.api.navi.model.RouteOverlayOptions; +import com.amap.api.navi.view.RouteOverLay; +import com.mogo.map.impl.amap.utils.MapStyleUtils; +import com.mogo.utils.logger.Logger; + +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; + +/** + * @author congtaowang + * @since 2019-10-04 + *

+ * 路径覆盖物 + */ +public class RouteOverLayWrapper { + + private static final String TAG = "RouteOverLayWrapper"; + + private final WeakReference< Context > mContextRef; + private final AMap mAMap; + private final AMapNaviPath mPath; + + private RouteOverLay mRouteOverLay; + private boolean mIsRemoved = true; + + private boolean mIsTrafficLightsVisible = true; + private int mStartBitmapResId = 0; + private int mEndBitmapResId = 0; + private int mZIndex = 0; + + private static RouteOverlayOptions sOptions; + + public RouteOverLayWrapper( Context context, + AMap mAMap, + AMapNaviPath mPath ) { + this.mContextRef = new WeakReference<>( context ); + this.mAMap = mAMap; + this.mPath = mPath; + } + + public void addToMap() { + if ( mContextRef == null || mContextRef.get() == null ) { + return; + } + mRouteOverLay = new RouteOverLay( mAMap, mPath, mContextRef.get() ); + if ( sOptions == null ) { + sOptions = MapStyleUtils.getRouteOverlayOptions(); + } + mRouteOverLay.setRouteOverlayOptions( sOptions ); + mRouteOverLay.setTrafficLine( true ); + mRouteOverLay.setRouteOverlayVisible( true ); + mRouteOverLay.setTrafficLightsVisible( true ); + mRouteOverLay.setArrowOnRoute( true ); + mRouteOverLay.setZindex( mZIndex ); + mRouteOverLay.setNaviArrowVisible( true ); + mRouteOverLay.setLightsVisible( true ); + mRouteOverLay.setTrafficLightsVisible( mIsTrafficLightsVisible ); + hookRouteArrow(); + + if ( mStartBitmapResId != 0 ) { + try { + mRouteOverLay.setStartPointBitmap( BitmapFactory.decodeResource( mContextRef.get().getResources(), mStartBitmapResId ) ); + } catch ( Exception e ) { + e.printStackTrace(); + } + } else { + mRouteOverLay.setStartPointBitmap( null ); + } + + if ( mEndBitmapResId != 0 ) { + try { + mRouteOverLay.setEndPointBitmap( BitmapFactory.decodeResource( mContextRef.get().getResources(), mEndBitmapResId ) ); + } catch ( Exception e ) { + e.printStackTrace(); + } + } else { + mRouteOverLay.setEndPointBitmap( null ); + } + + mRouteOverLay.addToMap(); + mIsRemoved = false; + } + + public void remove() { + Log.d( TAG, "remove" ); + if ( mRouteOverLay != null ) { + try { + mRouteOverLay.removeFromMap(); + mIsRemoved = true; + } catch ( Exception e ) { + e.printStackTrace(); + } + } + } + + /** + * 设置透明度 + * + * @param alpha + */ + public void setTransparency( float alpha ) { + if ( mRouteOverLay != null ) { + mRouteOverLay.setTransparency( alpha ); + } + } + + public RouteOverLayWrapper setTrafficLightsVisible( boolean visible ) { + mIsTrafficLightsVisible = visible; + return this; + } + + public RouteOverLayWrapper setStartBitmap( int startBitmapResId ) { + mStartBitmapResId = startBitmapResId; + return this; + } + + public RouteOverLayWrapper setEndBitmap( int endBitmapResId ) { + mEndBitmapResId = endBitmapResId; + return this; + } + + public RouteOverLayWrapper setZIndex( int zIndex ) { + mZIndex = zIndex; + return this; + } + + public int getZIndex() { + return mZIndex; + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + mIsRemoved = true; + } + + public synchronized boolean isRemoved() { + return mIsRemoved; + } + + public void updatePolyline( AMapNaviLocation aMapNaviLocation ) { + if ( mIsRemoved ) { + return; + } + if ( mRouteOverLay != null ) { + mRouteOverLay.updatePolyline( aMapNaviLocation ); + } + } + + public void drawArrow( NaviInfo naviInfo ) { + Log.d( TAG, "drawArrow" ); + if ( mIsRemoved ) { + return; + } + if ( naviInfo == null ) { + return; + } + if ( mRouteOverLay != null ) { + try { + mRouteOverLay.drawArrow( mRouteOverLay.getArrowPoints( naviInfo.getCurStep() ) ); + } catch ( Exception e ) { + e.printStackTrace(); + } + } + } + + private void hookRouteArrow() { + if ( mRouteOverLay != null && sOptions != null ) { + try { + Field field = mRouteOverLay.getClass().getDeclaredField( "naviArrow" ); + field.setAccessible( true ); + field.set( mRouteOverLay, mAMap.addNavigateArrow( new NavigateArrowOptions().topColor( sOptions.getArrowColor() ).width( sOptions.getLineWidth() ).sideColor( sOptions.getArrowSideColor() ) ) ); + Logger.d( TAG, "hook 成功。" ); + } catch ( Exception e ) { + e.printStackTrace(); + } + } + } + + public Polyline getTrafficColorfulPolyline() { + if ( mRouteOverLay != null ) { + return mRouteOverLay.mTrafficColorfulPolyline; + } + return null; + } + + public void destroy() { + Log.d( TAG, "destroy" ); + if ( mRouteOverLay != null ) { + try { + mRouteOverLay.destroy(); + mIsRemoved = true; + } catch ( Exception e ) { + e.printStackTrace(); + } + } + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/RouteOverlay.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/RouteOverlay.java new file mode 100755 index 0000000000..3dcae30d10 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/RouteOverlay.java @@ -0,0 +1,236 @@ +package com.mogo.map.impl.amap.overlay; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Color; + +import com.amap.api.maps.AMap; +import com.amap.api.maps.CameraUpdateFactory; +import com.amap.api.maps.model.BitmapDescriptor; +import com.amap.api.maps.model.BitmapDescriptorFactory; +import com.amap.api.maps.model.LatLng; +import com.amap.api.maps.model.LatLngBounds; +import com.amap.api.maps.model.Marker; +import com.amap.api.maps.model.MarkerOptions; +import com.amap.api.maps.model.Polyline; +import com.amap.api.maps.model.PolylineOptions; +import com.mogo.map.impl.amap.R; + +import java.util.ArrayList; +import java.util.List; + + +public class RouteOverlay { + protected List stationMarkers = new ArrayList(); + protected List allPolyLines = new ArrayList(); + protected Marker startMarker; + protected Marker endMarker; + protected LatLng startPoint; + protected LatLng endPoint; + protected AMap mAMap; + private Context mContext; + private Bitmap startBit, endBit, busBit, walkBit, driveBit; + protected boolean nodeIconVisible = true; + + public RouteOverlay(Context context) { + mContext = context; + } + + /** + * 去掉BusRouteOverlay上所有的Marker。 + * + * @since V2.1.0 + */ + public void removeFromMap() { + if (startMarker != null) { + startMarker.remove(); + + } + if (endMarker != null) { + endMarker.remove(); + } + for (Marker marker : stationMarkers) { + marker.remove(); + } + for (Polyline line : allPolyLines) { + line.remove(); + } + destroyBit(); + } + + private void destroyBit() { + if (startBit != null) { + startBit.recycle(); + startBit = null; + } + if (endBit != null) { + endBit.recycle(); + endBit = null; + } + if (busBit != null) { + busBit.recycle(); + busBit = null; + } + if (walkBit != null) { + walkBit.recycle(); + walkBit = null; + } + if (driveBit != null) { + driveBit.recycle(); + driveBit = null; + } + } + + /** + * 给起点Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。 + * + * @return 更换的Marker图片。 + * @since V2.1.0 + */ + protected BitmapDescriptor getStartBitmapDescriptor() { + return BitmapDescriptorFactory.fromResource( R.drawable.amap_start); + } + + /** + * 给终点Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。 + * + * @return 更换的Marker图片。 + * @since V2.1.0 + */ + protected BitmapDescriptor getEndBitmapDescriptor() { + return BitmapDescriptorFactory.fromResource(R.drawable.amap_end); + } + + /** + * 给公交Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。 + * + * @return 更换的Marker图片。 + * @since V2.1.0 + */ + protected BitmapDescriptor getBusBitmapDescriptor() { + return BitmapDescriptorFactory.fromResource(R.drawable.amap_bus); + } + + /** + * 给步行Marker设置图标,并返回更换图标的图片。如不用默认图片,需要重写此方法。 + * + * @return 更换的Marker图片。 + * @since V2.1.0 + */ + protected BitmapDescriptor getWalkBitmapDescriptor() { + return BitmapDescriptorFactory.fromResource(R.drawable.amap_man); + } + + protected BitmapDescriptor getDriveBitmapDescriptor() { + return BitmapDescriptorFactory.fromResource(R.drawable.amap_car); + } + + protected void addStartAndEndMarker() { + startMarker = mAMap.addMarker((new MarkerOptions()) + .position(startPoint).icon(getStartBitmapDescriptor()) + .title("\u8D77\u70B9")); + // startMarker.showInfoWindow(); + + endMarker = mAMap.addMarker((new MarkerOptions()).position(endPoint) + .icon(getEndBitmapDescriptor()).title("\u7EC8\u70B9")); + // mAMap.moveCamera(CameraUpdateFactory.newLatLngZoom(startPoint, + // getShowRouteZoom())); + } + + /** + * 移动镜头到当前的视角。 + * + * @since V2.1.0 + */ + public void zoomToSpan() { + if (startPoint != null) { + if (mAMap == null) + return; + try { + LatLngBounds bounds = getLatLngBounds(); + mAMap.animateCamera(CameraUpdateFactory + .newLatLngBounds(bounds, 50)); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + protected LatLngBounds getLatLngBounds() { + LatLngBounds.Builder b = LatLngBounds.builder(); + b.include(new LatLng(startPoint.latitude, startPoint.longitude)); + b.include(new LatLng(endPoint.latitude, endPoint.longitude)); + for (Polyline polyline : allPolyLines) { + for (LatLng point : polyline.getPoints()) { + b.include(point); + } + } + return b.build(); + } + + /** + * 路段节点图标控制显示接口。 + * + * @param visible true为显示节点图标,false为不显示。 + * @since V2.3.1 + */ + public void setNodeIconVisibility(boolean visible) { + try { + nodeIconVisible = visible; + if (this.stationMarkers != null && this.stationMarkers.size() > 0) { + for (int i = 0; i < this.stationMarkers.size(); i++) { + this.stationMarkers.get(i).setVisible(visible); + } + } + } catch (Throwable e) { + e.printStackTrace(); + } + } + + protected void addStationMarker(MarkerOptions options) { + if (options == null) { + return; + } + Marker marker = mAMap.addMarker(options); + if (marker != null) { + stationMarkers.add(marker); + } + + } + + protected void addPolyLine(PolylineOptions options) { + if (options == null) { + return; + } + Polyline polyline = mAMap.addPolyline(options); + if (polyline != null) { + allPolyLines.add(polyline); + } + } + + protected float getRouteWidth() { + return 18f; + } + + protected int getWalkColor() { + return Color.parseColor("#6db74d"); + } + + /** + * 自定义路线颜色。 + * return 自定义路线颜色。 + * + * @since V2.2.1 + */ + protected int getBusColor() { + return Color.parseColor("#537edc"); + } + + protected int getDriveColor() { + return Color.parseColor("#537edc"); + } + + // protected int getShowRouteZoom() { + // return 15; + // } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/RouteOverlayHelper.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/RouteOverlayHelper.java new file mode 100644 index 0000000000..2cdbc7ff32 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/overlay/RouteOverlayHelper.java @@ -0,0 +1,97 @@ +package com.mogo.map.impl.amap.overlay; + +import android.content.Context; + +import com.amap.api.services.core.LatLonPoint; +import com.amap.api.services.route.DriveRouteResult; +import com.amap.api.services.route.RouteSearch; +import com.mogo.map.MogoLatLng; +import com.mogo.map.impl.amap.AMapWrapper; +import com.mogo.map.impl.amap.InterceptorHandler; +import com.mogo.utils.logger.Logger; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author congtaowang + * @since 2020-01-08 + *

+ * 给定起点、途经点,规划路径 + */ +public class RouteOverlayHelper { + + private static final String TAG = "RouteOverlayHelper"; + + private static volatile RouteOverlayHelper sInstance; + + private DrivingRouteOverlay mDrivingRouteOverlay; + + private RouteOverlayHelper() { + } + + public static RouteOverlayHelper getInstance() { + if ( sInstance == null ) { + synchronized ( RouteOverlayHelper.class ) { + if ( sInstance == null ) { + sInstance = new RouteOverlayHelper(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + public void addRouteWay( final Context context, MogoLatLng start, MogoLatLng end, List< MogoLatLng > wayPoints ) { + if ( wayPoints == null || wayPoints.isEmpty() ) { + return; + } + if ( InterceptorHandler.getInstance().ignoreDrawRouteOverlay( context ) ) { + Logger.w( TAG, "naviing." ); + return; + } + + if ( mDrivingRouteOverlay != null ) { + mDrivingRouteOverlay.removeFromMap(); + } + + RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo( new LatLonPoint( start.lat, start.lng ), + new LatLonPoint( end.lat, end.lng ) ); + final List< LatLonPoint > ways = new ArrayList<>(); + for ( MogoLatLng wayPoint : wayPoints ) { + ways.add( new LatLonPoint( wayPoint.lat, wayPoint.lng ) ); + } + RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery( fromAndTo, 0, ways, null, "" ); + RouteSearch routeSearch = new RouteSearch( context ); + routeSearch.calculateDriveRouteAsyn( query ); + routeSearch.setRouteSearchListener( new OnRouteSearchListenerAdapter() { + @Override + public void onDriveRouteSearched( DriveRouteResult driveRouteResult, int i ) { + super.onDriveRouteSearched( driveRouteResult, i ); + if ( i != 1000 ) { + Logger.e( TAG, "算路失败. code = %d", i ); + return; + } + mDrivingRouteOverlay = new DrivingRouteOverlay( context, AMapWrapper.getAMap(), + driveRouteResult.getPaths().get( 0 ), + driveRouteResult.getStartPos(), + driveRouteResult.getTargetPos(), + null ); + mDrivingRouteOverlay.setNodeIconVisibility( false ); + mDrivingRouteOverlay.setIsColorfulline( false ); + mDrivingRouteOverlay.addToMap(); + mDrivingRouteOverlay.zoomToSpan(); + } + } ); + } + + public void removeAll() { + if ( mDrivingRouteOverlay != null ) { + mDrivingRouteOverlay.removeFromMap(); + } + mDrivingRouteOverlay = null; + } +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/amap/search/GeocodeSearchClient.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/GeocodeSearchClient.java similarity index 85% rename from libraries/mogo-map/src/main/java/com/mogo/map/amap/search/GeocodeSearchClient.java rename to libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/GeocodeSearchClient.java index 974ae5563d..4de829cd54 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/amap/search/GeocodeSearchClient.java +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/GeocodeSearchClient.java @@ -1,4 +1,4 @@ -package com.mogo.map.amap.search; +package com.mogo.map.impl.amap.search; import android.content.Context; @@ -8,14 +8,14 @@ import com.amap.api.services.geocoder.GeocodeResult; import com.amap.api.services.geocoder.GeocodeSearch; import com.amap.api.services.geocoder.RegeocodeAddress; import com.amap.api.services.geocoder.RegeocodeResult; -import com.mogo.map.amap.utils.ObjectUtils; import com.mogo.map.exception.MogoMapException; -import com.mogo.map.search.IMogoGeoSearch; -import com.mogo.map.search.IMogoGeoSearchListener; -import com.mogo.map.search.MogoGeocodeAddress; -import com.mogo.map.search.MogoRegeocodeAddress; -import com.mogo.map.search.query.MogoGeocodeQuery; -import com.mogo.map.search.query.MogoRegeocodeQuery; +import com.mogo.map.impl.amap.utils.ObjectUtils; +import com.mogo.map.search.geo.IMogoGeoSearch; +import com.mogo.map.search.geo.IMogoGeoSearchListener; +import com.mogo.map.search.geo.MogoGeocodeAddress; +import com.mogo.map.search.geo.MogoRegeocodeAddress; +import com.mogo.map.search.geo.query.MogoGeocodeQuery; +import com.mogo.map.search.geo.query.MogoRegeocodeQuery; import java.util.ArrayList; import java.util.List; @@ -88,14 +88,20 @@ public class GeocodeSearchClient implements IMogoGeoSearch, GeocodeSearch.OnGeoc @Override public void onRegeocodeSearched( RegeocodeResult regeocodeResult, int i ) { if ( mListener != null ) { - mListener.onRegeocodeSearched( ObjectUtils.fromAMap( regeocodeResult ), i ); + mListener.onRegeocodeSearched( ObjectUtils.fromAMap( regeocodeResult ) ); } } @Override public void onGeocodeSearched( GeocodeResult geocodeResult, int i ) { if ( mListener != null ) { - mListener.onGeocodeSearched( ObjectUtils.fromAMap( geocodeResult ), i ); + mListener.onGeocodeSearched( ObjectUtils.fromAMap( geocodeResult ) ); } } + + @Override + public void destroy() { + mClient = null; + mListener = null; + } } diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/InputtipsSearch.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/InputtipsSearch.java new file mode 100644 index 0000000000..7ce2a7013f --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/InputtipsSearch.java @@ -0,0 +1,88 @@ +package com.mogo.map.impl.amap.search; + +import android.content.Context; + +import com.amap.api.services.core.AMapException; +import com.amap.api.services.help.Inputtips; +import com.amap.api.services.help.InputtipsQuery; +import com.amap.api.services.help.Tip; +import com.mogo.map.exception.MogoMapException; +import com.mogo.map.impl.amap.utils.ObjectUtils; +import com.mogo.map.search.inputtips.IMogoInputtipsListener; +import com.mogo.map.search.inputtips.IMogoInputtipsSearch; +import com.mogo.map.search.inputtips.MogoTip; +import com.mogo.map.search.inputtips.query.MogoInputtipsQuery; +import com.mogo.utils.logger.Logger; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-20 + *

+ * 高德地图 inputtips搜索实现 + */ +public class InputtipsSearch implements IMogoInputtipsSearch, Inputtips.InputtipsListener { + + private static final String TAG = "InputtipsSearch"; + + private Inputtips mClient; + private InputtipsQuery mQuery; + private IMogoInputtipsListener mListener; + + public InputtipsSearch(Context context, MogoInputtipsQuery query) { + mQuery = ObjectUtils.fromMogo(query); + mClient = new Inputtips(context, mQuery); + mClient.setInputtipsListener(this); + } + + @Override + public void setQuery(MogoInputtipsQuery query) { + this.mQuery = ObjectUtils.fromMogo(query); + } + + @Override + public void setInputtipsListener(IMogoInputtipsListener listener) { + this.mListener = listener; + } + + @Override + public void requestInputtipsAsyn() { + if (mClient != null) { + mClient.requestInputtipsAsyn(); + } + } + + @Override + public void onGetInputtips(List list, int i) { + if (i == 1000) { + if (mListener != null) { + mListener.onGetInputtips(getResult(list)); + } + } else { + Logger.e(TAG, "errorcode = " + i); + } + } + + private List getResult(List tips) { + List mogoTips = new ArrayList<>(); + if (tips != null) { + //只添加有坐标的结果 + for (Tip tip : tips) { + MogoTip mogoTip = ObjectUtils.fromAMap(tip); + if (mogoTip != null && mogoTip.getPoint() != null) { + mogoTips.add(mogoTip); + } + } + } + return mogoTips; + } + + @Override + public void destroy() { + mClient = null; + mListener = null; + mQuery = null; + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/PoiSearchClient.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/PoiSearchClient.java new file mode 100644 index 0000000000..ccefac7867 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/PoiSearchClient.java @@ -0,0 +1,130 @@ +package com.mogo.map.impl.amap.search; + +import android.content.Context; + +import com.amap.api.services.core.AMapException; +import com.amap.api.services.core.PoiItem; +import com.amap.api.services.poisearch.PoiResult; +import com.amap.api.services.poisearch.PoiSearch; +import com.mogo.map.exception.MogoMapException; +import com.mogo.map.impl.amap.utils.ObjectUtils; +import com.mogo.map.search.geo.MogoPoiItem; +import com.mogo.map.search.poisearch.IMogoPoiSearch; +import com.mogo.map.search.poisearch.IMogoPoiSearchListener; +import com.mogo.map.search.poisearch.MogoPoiResult; +import com.mogo.map.search.poisearch.MogoSearchBound; +import com.mogo.map.search.poisearch.query.MogoPoiSearchQuery; +import com.mogo.utils.logger.Logger; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * poi搜索高德实现 + *

+ * 错误码对照表:https://lbs.amap.com/api/android-sdk/guide/map-tools/error-code + */ +public class PoiSearchClient implements IMogoPoiSearch, PoiSearch.OnPoiSearchListener { + + private static final String TAG = "PoiSearchClient"; + + private MogoPoiSearchQuery mQuery; + private PoiSearch mClient; + private IMogoPoiSearchListener mListener; + private MogoSearchBound mBound; + + public PoiSearchClient( Context context, MogoPoiSearchQuery query ) { + mQuery = query; + mClient = new PoiSearch( context, ObjectUtils.fromMogo( mQuery ) ); + mClient.setOnPoiSearchListener( this ); + } + + @Override + public void setPoiSearchListener( IMogoPoiSearchListener listener ) { + mListener = listener; + } + + @Override + public void searchPOIAsyn() { + if ( mClient != null ) { + mClient.searchPOIAsyn(); + } + } + + @Override + public MogoPoiResult searchPOI() throws MogoMapException { + if ( mClient != null ) { + try { + PoiResult search = mClient.searchPOI(); + return ObjectUtils.fromAMap( search ); + } catch ( AMapException e ) { + throw new MogoMapException( e ); + } + } + return null; + } + + @Override + public void setQuery( MogoPoiSearchQuery query ) { + mQuery = query; + if ( mClient != null ) { + mClient.setQuery( ObjectUtils.fromMogo( mQuery ) ); + } + } + + @Override + public MogoPoiItem searchPOIId( String poiId ) throws MogoMapException { + if ( mClient != null ) { + try { + PoiItem poiItem = mClient.searchPOIId( poiId ); + return ObjectUtils.fromAMap( poiItem ); + } catch ( AMapException e ) { + throw new MogoMapException( e ); + } + } + return null; + } + + @Override + public void searchPOIIdAsyn( String poiId ) { + if ( mClient != null ) { + mClient.searchPOIIdAsyn( poiId ); + } + } + + @Override + public void setBound( MogoSearchBound bound ) { + mBound = bound; + if ( mClient != null ) { + mClient.setBound( ObjectUtils.fromMogo( mBound ) ); + } + } + + @Override + public void onPoiSearched( PoiResult poiResult, int errorCode ) { + if ( errorCode != 1000 ) { + Logger.e( TAG, "errorcode is %d", errorCode ); + } + if ( mListener != null ) { + mListener.onPoiSearched( ObjectUtils.fromAMap( poiResult ), errorCode ); + } + } + + @Override + public void onPoiItemSearched( PoiItem poiItem, int errorCode ) { + if ( errorCode != 1000 ) { + Logger.e( TAG, "errorcode is %d", errorCode ); + } + if ( mListener != null ) { + mListener.onPoiItemSearched( ObjectUtils.fromAMap( poiItem ), errorCode ); + } + } + + @Override + public void destroy() { + mQuery = null; + mClient = null; + mListener = null; + mBound = null; + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/RoadSearchClient.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/RoadSearchClient.java new file mode 100644 index 0000000000..55dc81ad65 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/search/RoadSearchClient.java @@ -0,0 +1,140 @@ +package com.mogo.map.impl.amap.search; + +import android.content.Context; + +import com.amap.api.services.core.LatLonPoint; +import com.amap.api.services.route.BusRouteResult; +import com.amap.api.services.route.DrivePath; +import com.amap.api.services.route.DriveRouteResult; +import com.amap.api.services.route.DriveStep; +import com.amap.api.services.route.RideRouteResult; +import com.amap.api.services.route.RouteSearch; +import com.amap.api.services.route.WalkRouteResult; +import com.mogo.map.MogoLatLng; +import com.mogo.map.impl.amap.utils.ObjectUtils; +import com.mogo.map.search.drive.IMogoRoadSearch; +import com.mogo.map.search.drive.IMogoRoadSearchListener; +import com.mogo.map.search.drive.MogoRoadSearchQuery; +import com.mogo.utils.logger.Logger; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author congtaowang + * @since 2020/6/1 + *

+ * 描述 + */ +public class RoadSearchClient implements IMogoRoadSearch, RouteSearch.OnRouteSearchListener { + + private static final String TAG = "DriveSearchClient"; + + private RouteSearch mRouteSearch; + private IMogoRoadSearchListener mListener; + + @Override + public void searchRoadPath( Context context, + MogoRoadSearchQuery query ) { + + if ( query == null ) { + return; + } + + if ( !checkPoint( query.mStart, "起点坐标" ) ) { + return; + } + + if ( !checkPoint( query.mTarget, "终点坐标" ) ) { + return; + } + + RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo( ObjectUtils.fromMogo( query.mStart ), ObjectUtils.fromMogo( query.mTarget ) ); + final List< LatLonPoint > latLonPointWays = new ArrayList<>(); + if ( query.mWays != null ) { + for ( MogoLatLng wayPoint : query.mWays ) { + if ( checkPoint( wayPoint, "途经点" ) ) { + latLonPointWays.add( ObjectUtils.fromMogo( wayPoint ) ); + } + } + } + + RouteSearch.DriveRouteQuery searchQuery = new RouteSearch.DriveRouteQuery( fromAndTo, RouteSearch.DRIVING_MULTI_CHOICE_AVOID_CONGESTION, latLonPointWays, null, "" ); + if ( mRouteSearch == null ) { + mRouteSearch = new RouteSearch( context ); + mRouteSearch.setRouteSearchListener(this); + } + mRouteSearch.calculateDriveRouteAsyn( searchQuery ); + } + + private boolean checkPoint( MogoLatLng latLng, String msg ) { + if ( latLng == null ) { + Logger.e( TAG, msg + " is null" ); + return false; + } + if ( latLng.lat <= 0d || latLng.lon <= 0d ) { + Logger.e( TAG, msg + " is not a valid " ); + return false; + } + return true; + } + + @Override + public void setRoadPathSearchListener( IMogoRoadSearchListener listener ) { + mListener = listener; + } + + @Override + public void onBusRouteSearched( BusRouteResult busRouteResult, int i ) { + + } + + @Override + public void onDriveRouteSearched( DriveRouteResult driveRouteResult, int i ) { + if ( mListener == null ) { + return; + } + List< MogoLatLng > points = new ArrayList<>(); + Logger.d(TAG,"onDriveRouteSearched i : " + i); + if ( driveRouteResult == null + || driveRouteResult.getPaths() == null + || driveRouteResult.getPaths().isEmpty() ) { + Logger.d(TAG,"onDriveRouteSearched result is null"); + mListener.onDrivePathSearched( null ); + return; + } + DrivePath drivePath = driveRouteResult.getPaths().get( 0 ); + int size = driveRouteResult.getPaths().size(); + Logger.d(TAG,"onDriveRouteSearched driveRouteResult size : " + size); + + List< DriveStep > steps = drivePath.getSteps(); + if ( steps == null || steps.isEmpty() ) { + mListener.onDrivePathSearched( null ); + return; + } + for ( DriveStep step : steps ) { + List< LatLonPoint > polylineList = step.getPolyline(); + if ( polylineList == null || polylineList.isEmpty() ) { + continue; + } + for ( LatLonPoint latLonPoint : polylineList ) { + MogoLatLng latLng = ObjectUtils.fromAMap( latLonPoint ); + if ( latLng == null ) { + continue; + } + points.add( latLng ); + } + } + mListener.onDrivePathSearched( points ); + } + + @Override + public void onWalkRouteSearched( WalkRouteResult walkRouteResult, int i ) { + + } + + @Override + public void onRideRouteSearched( RideRouteResult rideRouteResult, int i ) { + + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/uicontroller/AMapUIController.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/uicontroller/AMapUIController.java new file mode 100644 index 0000000000..2e874886ae --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/uicontroller/AMapUIController.java @@ -0,0 +1,279 @@ +package com.mogo.map.impl.amap.uicontroller; + +import android.graphics.Point; +import android.graphics.Rect; +import android.location.Location; +import android.view.View; +import android.view.animation.Interpolator; + +import com.mogo.map.MogoLatLng; +import com.mogo.map.MogoMap; +import com.mogo.map.marker.IMogoMarker; +import com.mogo.map.uicontroller.CarCursorOption; +import com.mogo.map.uicontroller.EnumMapUI; +import com.mogo.map.uicontroller.IMogoMapUIController; +import com.mogo.map.uicontroller.MapCameraPosition; +import com.mogo.map.uicontroller.MapControlResult; +import com.mogo.utils.logger.Logger; + +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-26 + *

+ * 描述 + */ +public class AMapUIController implements IMogoMapUIController { + + private static final String TAG = "AMapUIController"; + + private static volatile AMapUIController sInstance; + + private IMogoMapUIController mClient; + + private AMapUIController() { + } + + public static AMapUIController getInstance() { + if (sInstance == null) { + synchronized (AMapUIController.class) { + if (sInstance == null) { + sInstance = new AMapUIController(); + } + } + } + return sInstance; + } + + public void initClient(IMogoMapUIController client) { + this.mClient = client; + } + + public synchronized void release() { + sInstance = null; + } + + @Override + public void setTrafficEnabled(boolean visible) { + if (mClient != null) { + mClient.setTrafficEnabled(visible); + } + } + + @Override + public MapControlResult changeZoom( boolean zoom) { + if (mClient != null) { + return mClient.changeZoom(zoom); + } + return MapControlResult.ERROR; + } + + @Override + public MapControlResult changeZoom(float zoom) { + if (mClient != null) { + return mClient.changeZoom(zoom); + } + return MapControlResult.ERROR; + } + + @Override + public void changeMapMode(EnumMapUI mode) { + if (mClient != null) { + mClient.changeMapMode(mode); + } + } + + @Override + public void moveToCenter(MogoLatLng latLng, boolean animate) { + if (mClient != null) { + mClient.moveToCenter(latLng, animate); + } + } + + @Override + public void showMyLocation(boolean visible) { + if (mClient != null) { + mClient.showMyLocation(visible); + } + } + + @Override + public void showMyLocation( View view ) { + if ( mClient != null ) { + mClient.showMyLocation( view ); + } + } + + @Override + public void recoverLockMode() { + if (mClient != null) { + mClient.recoverLockMode(); + } + } + + @Override + public void loseLockMode() { + if ( mClient != null ) { + mClient.loseLockMode(); + } + } + + @Override + public void setLockZoom(int var1) { + if (mClient != null) { + mClient.setLockZoom(var1); + } + } + + @Override + public void displayOverview( Rect bounds ) { + if (mClient != null) { + mClient.displayOverview(bounds); + } + } + + @Override + public float getScalePerPixel() { + if (mClient != null) { + return mClient.getScalePerPixel(); + } + 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; + } + + @Override public MogoLatLng getWindowCenterLocation() { + if (mClient != null) { + return mClient.getWindowCenterLocation(); + } + return null; + } + + @Override + public void setPointToCenter(double mapCenterX, double mapCenterY) { + if (mClient != null) { + mClient.setPointToCenter(mapCenterX, mapCenterY); + } + } + + @Override + public Point getLocationPointInScreen(MogoLatLng latLng) { + if (mClient != null) { + return mClient.getLocationPointInScreen(latLng); + } + return null; + } + + @Override + public MogoLatLng getLocationMogoLatLngInScreen(Point point) { + if (mClient != null) { + return mClient.getLocationMogoLatLngInScreen(point); + } + return null; + } + + @Override + public void startJumpAnimation(IMogoMarker marker, float high, Interpolator interpolator, + long duration) { + if (mClient != null) { + mClient.startJumpAnimation(marker, high, interpolator, duration); + } + } + + @Override + public void setRenderFps(int fps) { + if (mClient != null) { + mClient.setRenderFps(fps); + } + } + + @Override + public void showBounds( String tag, MogoLatLng carPosition, List< MogoLatLng > lonLats, Rect bound, boolean lockCarPosition ) { + if ( mClient != null ) { + mClient.showBounds( tag, carPosition, lonLats, bound, lockCarPosition ); + } + } + + @Override + public void forceRender() { + if (mClient != null) { + mClient.forceRender(); + } + } + + @Override + public float calculateLineDistance( MogoLatLng p1, MogoLatLng p2 ) throws Exception { + if ( mClient != null ) { + return mClient.calculateLineDistance( p1, p2 ); + } + return 0; + } + + @Override + public EnumMapUI getCurrentUiMode() { + if ( mClient != null ) { + return mClient.getCurrentUiMode(); + } + return null; + } + + @Override + public void changeMyLocation( Location location ) { + if ( mClient != null ) { + mClient.changeMyLocation( location ); + } + } + + @Override + public boolean isCarLocked() { + if ( mClient != null ) { + return mClient.isCarLocked(); + } + return false; + } + + @Override + public void setCarCursorOption( CarCursorOption option ) { + if ( mClient != null ) { + mClient.setCarCursorOption( option ); + } + } + + @Override + public MapCameraPosition getMapCameraPosition() { + if ( mClient != null ) { + return mClient.getMapCameraPosition(); + } + return null; + } + + @Override + public void changeBearing( float bearing ) { + if ( mClient != null ) { + mClient.changeBearing( bearing ); + } + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/IconTypeUtils.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/IconTypeUtils.java new file mode 100644 index 0000000000..46657869d0 --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/IconTypeUtils.java @@ -0,0 +1,96 @@ +package com.mogo.map.impl.amap.utils; + +import android.content.Context; +import android.util.SparseArray; + +import com.amap.api.navi.enums.IconType; + +/** + * @author congtaowang + * @since 2019-09-29 + *

+ * 描述 + */ +public class IconTypeUtils { + + private static SparseArray< String > sIconName = new SparseArray<>(); + + static { + sIconName.put( IconType.ARRIVED_DESTINATION, "到达目的地" ); + sIconName.put( IconType.ARRIVED_SERVICE_AREA, "到达服务区" ); + sIconName.put( IconType.ARRIVED_TOLLGATE, "到达收费站" ); + sIconName.put( IconType.ARRIVED_TUNNEL, "到达隧道" ); + sIconName.put( IconType.ARRIVED_WAYPOINT, "到达途经点" ); + sIconName.put( IconType.BRIDGE, "通过桥" ); + sIconName.put( IconType.BY_ELEVATOR, "电梯换层" ); + sIconName.put( IconType.BY_ESCALATOR, "扶梯换层" ); + sIconName.put( IconType.BY_STAIR, "楼梯换层" ); + sIconName.put( IconType.CABLEWAY, "通过索道" ); + sIconName.put( IconType.CHANNEL, "通过通道" ); + sIconName.put( IconType.CROSSWALK, "通过人行横道" ); + sIconName.put( IconType.CRUISE_ROUTE, "通过游船路线" ); + sIconName.put( IconType.DEFAULT, "自车" ); + sIconName.put( IconType.ENTER_BUILDING, "进入建筑物" ); + sIconName.put( IconType.ENTER_ROUNDABOUT, "进入环岛" ); + sIconName.put( IconType.ENTRY_LEFT_RING, "进入环岛" ); + sIconName.put( IconType.ENTRY_LEFT_RING_CONTINUE, "绕环岛直行" ); + sIconName.put( IconType.ENTRY_LEFT_RING_LEFT, "绕环岛左转" ); + sIconName.put( IconType.ENTRY_LEFT_RING_RIGHT, "绕环岛右转" ); + sIconName.put( IconType.ENTRY_LEFTRINGU_TURN, "绕环岛调头" ); + sIconName.put( IconType.ENTRY_RING_CONTINUE, "绕环岛直行" ); + sIconName.put( IconType.ENTRY_RING_LEFT, "绕环岛左转" ); + sIconName.put( IconType.ENTRY_RING_RIGHT, "绕环岛右转" ); + sIconName.put( IconType.ENTRY_RING_UTURN, "绕环岛调头" ); + sIconName.put( IconType.FERRY, "通过轮渡" ); + sIconName.put( IconType.LADDER, "通过阶梯" ); + sIconName.put( IconType.LEAVE_BUILDING, "离开建筑物" ); + sIconName.put( IconType.LEAVE_LEFT_RING, "驶出环岛" ); + sIconName.put( IconType.LEFT, "左转" ); + sIconName.put( IconType.LEFT_BACK, "左后" ); + sIconName.put( IconType.LEFT_FRONT, "左前方" ); + sIconName.put( IconType.LEFT_TURN_AROUND, "左转掉头" ); + sIconName.put( IconType.LIFT, "通过直梯" ); + sIconName.put( IconType.LOW_CROSS, "通过普通路口" ); + sIconName.put( IconType.LOW_TRAFFIC_CROSS, "红绿灯路口" ); + sIconName.put( IconType.NONE, "无定义" ); + sIconName.put( IconType.OUT_ROUNDABOUT, "驶出环岛" ); + sIconName.put( IconType.OVERPASS, "通过过街天桥" ); + sIconName.put( IconType.PARK, "通过公园" ); + sIconName.put( IconType.RIGHT, "右转" ); + sIconName.put( IconType.RIGHT_BACK, "右后方" ); + sIconName.put( IconType.RIGHT_FRONT, "右前方" ); + sIconName.put( IconType.SIGHTSEEING_BUSLINE, "通过观光车路线" ); + sIconName.put( IconType.SKY_CHANNEL, "通过空中通道" ); + sIconName.put( IconType.SLIDEWAY, "通过滑道" ); + sIconName.put( IconType.SLOPE, "通过斜坡" ); + sIconName.put( IconType.SPECIAL_CONTINUE, "顺行" ); + sIconName.put( IconType.SQUARE, "通过广场" ); + sIconName.put( IconType.STAIRCASE, "通过扶梯" ); + sIconName.put( IconType.STRAIGHT, "直行" ); + sIconName.put( IconType.SUBWAY, "通过地铁通道" ); + sIconName.put( IconType.U_TURN_RIGHT, "右转掉头" ); + sIconName.put( IconType.UNDERPASS, "通过地下通道" ); + sIconName.put( IconType.WALK_ROAD, "通过行人道路" ); + } + + private static int lastIconType = 0; + private static int lastIconResId = 0; + + public static String getNameByIconType( int iconType ) { + return sIconName.get( iconType ); + } + + public static int getResIdByIconType( Context context, int iconType ) { + try { + if ( iconType == lastIconType ) { + return lastIconResId; + } + int target = context.getResources().getIdentifier( "ic_" + iconType, "drawable", context.getPackageName() ); + lastIconType = iconType; + lastIconResId = target; + return target; + } catch ( Exception e ) { + return -1; + } + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/MapStyleUtils.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/MapStyleUtils.java new file mode 100644 index 0000000000..82e1727d0a --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/MapStyleUtils.java @@ -0,0 +1,74 @@ +package com.mogo.map.impl.amap.utils; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Color; + +import com.amap.api.navi.model.RouteOverlayOptions; +import com.mogo.commons.AbsMogoApplication; +import com.mogo.map.impl.amap.R; +import com.mogo.utils.ResourcesHelper; +import com.mogo.utils.WindowUtils; + +/** + * @author congtaowang + * @since 2019-10-04 + *

+ * 描述 + */ +public class MapStyleUtils { + + enum ColorEnum { + route_overlay_line_normal( Color.parseColor( "#00C96D" ) ), + route_overlay_line_unknown( Color.parseColor( "#3CD26E" ) ), + route_overlay_line_slow( Color.parseColor( "#ECC71F" ) ), + route_overlay_line_very_traffic( Color.parseColor( "#E16262" ) ), + route_overlay_line_traffic( Color.parseColor( "#E88181" ) ), + transparent( Color.parseColor( "#00000000" ) ), + light_gray( Color.parseColor( "#334BD089" ) ); + + private int color; + + ColorEnum( int color ) { + this.color = color; + } + + public int getColor() { + return color; + } + } + + public static RouteOverlayOptions getRouteOverlayOptions() { + RouteOverlayOptions options = new RouteOverlayOptions(); + // 设置导航线路的宽度 + options.setLineWidth( AbsMogoApplication.getApp().getResources().getDimension(R.dimen.path_width) ); +// // 设置交通状况情况良好下的纹理位图 +// options.setSmoothTraffic( colorToBitmap( ColorEnum.route_overlay_line_normal.getColor() ) ); +// // 设置路线的图标 +// options.setNormalRoute( colorToBitmap( ColorEnum.route_overlay_line_normal.getColor() ) ); +// // 设置交通状况未知下的纹理位图 +// options.setUnknownTraffic( colorToBitmap( ColorEnum.route_overlay_line_unknown.getColor() ) ); +// // 设置交通状况迟缓下的纹理位图 +// options.setSlowTraffic( colorToBitmap( ColorEnum.route_overlay_line_slow.getColor() ) ); +// // 设置交通状况非常拥堵下的纹理位图 +// options.setVeryJamTraffic( colorToBitmap( ColorEnum.route_overlay_line_very_traffic.getColor() ) ); +// // 设置交通状况拥堵下的纹理位图 +// options.setJamTraffic( colorToBitmap( ColorEnum.route_overlay_line_traffic.getColor() ) ); +// // 设置浮于道路上的『小箭头』图标的纹理位图 +// options.setArrowOnTrafficRoute( colorToBitmap( ColorEnum.transparent.getColor() ) ); + // 自定义走过路线纹理,默认走过路线置灰功能为关,需要在AMapNaviViewOptions.setAfterRouteAutoGray(boolean)打开,该方法才生效 + options.setPassRoute( colorToBitmap( ColorEnum.light_gray.getColor() ) ); +// // 设置路线虚线纹理 +// options.setFairWayRes( colorToBitmap( ColorEnum.route_overlay_line_normal.getColor() ) ); + options.setArrowColor( Color.parseColor( "#92C9FF" ) ); // 高德地图内部配置颜色 + options.setArrowSideColor( Color.parseColor( "#4F9BF2" ) ); // 高德地图内部配置颜色 + return options; + } + + public static Bitmap colorToBitmap( int color ) { + Bitmap.Config config = Bitmap.Config.ARGB_8888; + Bitmap bitmap = Bitmap.createBitmap( 1, 1, config ); + bitmap.eraseColor( color ); + return bitmap; + } +} diff --git a/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/MogoMapUtils.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/MogoMapUtils.java new file mode 100644 index 0000000000..ee152da0cb --- /dev/null +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/MogoMapUtils.java @@ -0,0 +1,96 @@ +package com.mogo.map.impl.amap.utils; + +import com.amap.api.maps.model.LatLng; +import com.amap.api.maps.model.LatLngBounds; +import com.mogo.map.MogoLatLng; +import com.mogo.map.exception.MogoMapException; +import com.mogo.utils.logger.Logger; + +import java.util.List; + +/** + * @author congtaowang + * @since 2020-03-04 + *

+ * 地图工具类 + */ +public class MogoMapUtils { + + private static final String TAG = "MogoMapUtils"; + + public static LatLngBounds getLatLngBounds( MogoLatLng carPosition, List< MogoLatLng > lonLats, boolean lockCarPosition ) throws Exception { + + if ( lonLats == null || lonLats.isEmpty() ) { + throw new MogoMapException( "经纬度不能为null或空集合" ); + } + LatLngBounds.Builder builder = new LatLngBounds.Builder(); + for ( MogoLatLng lonLat : lonLats ) { + builder.include( ObjectUtils.fromMogo2( lonLat ) ); + } + if ( carPosition != null && !lockCarPosition ) { + builder.include( ObjectUtils.fromMogo2( carPosition ) ); + } + LatLngBounds latLngBounds = builder.build(); + if ( !lockCarPosition ) { + return latLngBounds; + } + + if ( carPosition == null ) { + throw new MogoMapException( "自车位置经纬度信息不能为空" ); + } + + if ( latLngBounds.northeast == null && latLngBounds.southwest == null ) { + return null; + } + + double south = 0.0; + double west = 0.0; + + double east = 0.0; + double north = 0.0; + + double dLat = 0.0; + double dLon = 0.0; + + if ( latLngBounds.northeast == null ) { + dLat = Math.abs( carPosition.lat - latLngBounds.southwest.latitude ); + dLon = Math.abs( carPosition.lng - latLngBounds.southwest.longitude ); + } else if ( latLngBounds.southwest == null ) { + dLat = Math.abs( carPosition.lat - latLngBounds.northeast.latitude ); + dLon = Math.abs( carPosition.lng - latLngBounds.northeast.longitude ); + } else { + final double dLat1 = Math.abs( carPosition.lat - latLngBounds.southwest.latitude ); + final double dLon1 = Math.abs( carPosition.lng - latLngBounds.southwest.longitude ); + final double dLat2 = Math.abs( carPosition.lat - latLngBounds.northeast.latitude ); + final double dLon2 = Math.abs( carPosition.lng - latLngBounds.northeast.longitude ); + dLat = dLat1 > dLat2 ? dLat1 : dLat2; + dLon = dLon1 > dLon2 ? dLon1 : dLon2; + } + + west = carPosition.lat - dLat; + south = carPosition.lng + dLon; + + east = carPosition.lat + dLat; + north = carPosition.lng - dLon; + + if ( south == 0.0 || west == 0.0 || east == 0.0 || north == 0.0 ) { + return null; + } + + if ( east < west ) { + double tmp = east; + east = west; + west = tmp; + } + + if( north < south ){ + double tmp = north; + north = south; + south = tmp; + } + + Logger.d( TAG, "west = %s, east = %s, north = %s, south = %s", west, east, north, south ); + + return new LatLngBounds.Builder().include( new LatLng( east, north ) ).include( new LatLng( west, south ) ).build(); + } +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/amap/utils/ObjectUtils.java b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/ObjectUtils.java similarity index 58% rename from libraries/mogo-map/src/main/java/com/mogo/map/amap/utils/ObjectUtils.java rename to libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/ObjectUtils.java index 76222d54f2..f814b9f053 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/amap/utils/ObjectUtils.java +++ b/libraries/map-amap/src/main/java/com/mogo/map/impl/amap/utils/ObjectUtils.java @@ -1,12 +1,22 @@ -package com.mogo.map.amap.utils; +package com.mogo.map.impl.amap.utils; +import android.content.Context; import android.graphics.Bitmap; +import android.view.View; import com.amap.api.location.AMapLocation; import com.amap.api.maps.model.BitmapDescriptor; import com.amap.api.maps.model.BitmapDescriptorFactory; +import com.amap.api.maps.model.CameraPosition; import com.amap.api.maps.model.LatLng; import com.amap.api.maps.model.MarkerOptions; +import com.amap.api.maps.model.Poi; +import com.amap.api.maps.model.PolylineOptions; +import com.amap.api.navi.model.AMapCongestionLink; +import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo; +import com.amap.api.navi.model.AimLessModeCongestionInfo; +import com.amap.api.navi.model.NaviInfo; +import com.amap.api.navi.model.NaviLatLng; import com.amap.api.services.core.LatLonPoint; import com.amap.api.services.core.PoiItem; import com.amap.api.services.geocoder.AoiItem; @@ -24,31 +34,46 @@ import com.amap.api.services.help.Tip; import com.amap.api.services.poisearch.IndoorData; import com.amap.api.services.poisearch.Photo; import com.amap.api.services.poisearch.PoiItemExtension; +import com.amap.api.services.poisearch.PoiResult; +import com.amap.api.services.poisearch.PoiSearch; import com.amap.api.services.poisearch.SubPoiItem; import com.amap.api.services.road.Crossroad; import com.mogo.map.MogoLatLng; import com.mogo.map.location.MogoLocation; +import com.mogo.map.marker.IMogoMarkerIconViewCreator; import com.mogo.map.marker.MogoMarkerOptions; -import com.mogo.map.search.MogoAoiItem; -import com.mogo.map.search.MogoBusinessArea; -import com.mogo.map.search.MogoCrossroad; -import com.mogo.map.search.MogoGeocodeAddress; -import com.mogo.map.search.MogoGeocodeResult; -import com.mogo.map.search.MogoIndoorData; -import com.mogo.map.search.MogoPhoto; -import com.mogo.map.search.MogoPoiItem; -import com.mogo.map.search.MogoPoiItemExtension; -import com.mogo.map.search.MogoRegeocodeAddress; -import com.mogo.map.search.MogoRegeocodeResult; -import com.mogo.map.search.MogoRegeocodeRoad; -import com.mogo.map.search.MogoStreetNumber; -import com.mogo.map.search.MogoSubPoiItem; -import com.mogo.map.search.MogoTip; -import com.mogo.map.search.query.MogoGeocodeQuery; -import com.mogo.map.search.query.MogoInputtipsQuery; -import com.mogo.map.search.query.MogoRegeocodeQuery; +import com.mogo.map.model.MogoPoi; +import com.mogo.map.navi.MogoCongestionInfo; +import com.mogo.map.navi.MogoCongestionLink; +import com.mogo.map.navi.MogoNaviInfo; +import com.mogo.map.navi.MogoNaviListenerHandler; +import com.mogo.map.navi.MogoTraffic; +import com.mogo.map.overlay.MogoPolylineOptions; +import com.mogo.map.search.geo.MogoAoiItem; +import com.mogo.map.search.geo.MogoBusinessArea; +import com.mogo.map.search.geo.MogoCrossroad; +import com.mogo.map.search.geo.MogoGeocodeAddress; +import com.mogo.map.search.geo.MogoGeocodeResult; +import com.mogo.map.search.geo.MogoIndoorData; +import com.mogo.map.search.geo.MogoPhoto; +import com.mogo.map.search.geo.MogoPoiItem; +import com.mogo.map.search.geo.MogoPoiItemExtension; +import com.mogo.map.search.geo.MogoRegeocodeAddress; +import com.mogo.map.search.geo.MogoRegeocodeResult; +import com.mogo.map.search.geo.MogoRegeocodeRoad; +import com.mogo.map.search.geo.MogoStreetNumber; +import com.mogo.map.search.geo.MogoSubPoiItem; +import com.mogo.map.search.geo.query.MogoGeocodeQuery; +import com.mogo.map.search.geo.query.MogoRegeocodeQuery; +import com.mogo.map.search.inputtips.MogoTip; +import com.mogo.map.search.inputtips.query.MogoInputtipsQuery; +import com.mogo.map.search.poisearch.MogoPoiResult; +import com.mogo.map.search.poisearch.MogoSearchBound; +import com.mogo.map.search.poisearch.query.MogoPoiSearchQuery; +import com.mogo.map.uicontroller.MapCameraPosition; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; /** @@ -71,15 +96,19 @@ public class ObjectUtils { if ( icon == null || icon.isRecycled() ) { continue; } + descriptors.add( BitmapDescriptorFactory.fromBitmap( icon ) ); } } + BitmapDescriptor descriptor = getBitmapDescriptorFromMogo( opt ); + return new MarkerOptions() .position( new LatLng( opt.getLatitude(), opt.getLongitude() ) ) .title( opt.getTitle() ) .snippet( opt.getSnippet() ) - .icon( BitmapDescriptorFactory.fromBitmap( opt.getIcon() ) ) + .icon( descriptor ) + .anchor( opt.getU(), opt.getV() ) .icons( descriptors ) .period( opt.getPeriod() ) .rotateAngle( opt.getRotate() ) @@ -94,6 +123,21 @@ public class ObjectUtils { .zIndex( opt.getzIndex() ); } + private static BitmapDescriptor getBitmapDescriptorFromMogo( MogoMarkerOptions options ) { + if ( options == null ) { + return null; + } + Bitmap icon = options.getIcon(); + if ( icon != null ) { + return BitmapDescriptorFactory.fromBitmap( icon ); + } + View view = options.getIconView(); + if ( view != null ) { + return BitmapDescriptorFactory.fromView( view ); + } + return null; + } + public static MogoLocation fromAMap( AMapLocation aLocation ) { if ( aLocation == null ) { @@ -136,6 +180,20 @@ public class ObjectUtils { return new LatLonPoint( latLng.lat, latLng.lng ); } + public static NaviLatLng fromMogoAsNavi( MogoLatLng latLng ) { + if ( latLng == null ) { + return null; + } + return new NaviLatLng( latLng.lat, latLng.lng ); + } + + public static LatLng fromMogo2( MogoLatLng latLng ) { + if ( latLng == null ) { + return null; + } + return new LatLng( latLng.lat, latLng.lng ); + } + public static MogoLatLng fromAMap( LatLonPoint point ) { if ( point == null ) { return null; @@ -143,6 +201,13 @@ public class ObjectUtils { return new MogoLatLng( point.getLatitude(), point.getLongitude() ); } + public static MogoLatLng CameraPositionfromAMap( LatLng point ) { + if ( point == null ) { + return null; + } + return new MogoLatLng( point.latitude, point.longitude ); + } + public static GeocodeQuery fromMogo( MogoGeocodeQuery query ) { if ( query == null ) { return null; @@ -216,7 +281,7 @@ public class ObjectUtils { } public static MogoGeocodeResult fromAMap( GeocodeResult result ) { - if ( result == null || result.getGeocodeAddressList() != null ) { + if ( result == null || result.getGeocodeAddressList() == null ) { return null; } MogoGeocodeResult mogoGeocodeResult = new MogoGeocodeResult(); @@ -463,4 +528,228 @@ public class ObjectUtils { mogoTip.setTypeCode( tip.getTypeCode() ); return mogoTip; } + + public static MogoPoi fromAMap( Poi poi ) { + if ( poi == null ) { + return null; + } + MogoPoi mogoPoi = new MogoPoi(); + mogoPoi.setCoordinate( fromAMap( poi.getCoordinate() ) ); + mogoPoi.setName( poi.getName() ); + mogoPoi.setPoiId( poi.getPoiId() ); + return mogoPoi; + } + + public static MogoPoiSearchQuery fromAMap( PoiSearch.Query query ) { + if ( query == null ) { + return null; + } + MogoPoiSearchQuery mogoPoiSearchQuery = new MogoPoiSearchQuery( query.getQueryString(), query.getCategory(), query.getCity() ); + mogoPoiSearchQuery.setBuilding( query.getBuilding() ); + mogoPoiSearchQuery.setCityLimit( query.getCityLimit() ); + mogoPoiSearchQuery.setDistanceSort( query.isDistanceSort() ); + mogoPoiSearchQuery.setLocation( fromAMap( query.getLocation() ) ); + mogoPoiSearchQuery.setPageNum( query.getPageNum() ); + mogoPoiSearchQuery.setPageSize( query.getPageSize() ); + return mogoPoiSearchQuery; + } + + public static PoiSearch.Query fromMogo( MogoPoiSearchQuery query ) { + if ( query == null ) { + return null; + } + PoiSearch.Query psq = new PoiSearch.Query( query.getQuery(), query.getCategory(), query.getCity() ); + psq.setBuilding( query.getBuilding() ); + psq.setCityLimit( query.isCityLimit() ); + psq.setDistanceSort( query.isDistanceSort() ); + psq.setLocation( fromMogo( query.getLocation() ) ); + psq.setPageNum( query.getPageNum() ); + psq.setPageSize( query.getPageSize() ); + return psq; + } + + public static MogoSearchBound fromAMap( PoiSearch.SearchBound bound ) { + if ( bound == null ) { + return null; + } + if ( bound.getShape() == PoiSearch.SearchBound.BOUND_SHAPE ) { + return new MogoSearchBound( fromAMap( bound.getCenter() ), bound.getRange(), bound.isDistanceSort() ); + } else if ( bound.getShape() == PoiSearch.SearchBound.POLYGON_SHAPE ) { + return new MogoSearchBound( fromAMap( bound.getPolyGonList() ) ); + } else if ( bound.getShape() == PoiSearch.SearchBound.RECTANGLE_SHAPE ) { + return new MogoSearchBound( fromAMap( bound.getLowerLeft() ), fromAMap( bound.getUpperRight() ) ); + } + return null; + } + + public static List< MogoLatLng > fromAMap( List< LatLonPoint > latLngs ) { + if ( latLngs == null ) { + return null; + } + List< MogoLatLng > result = new ArrayList<>( latLngs.size() ); + for ( LatLonPoint latLng : latLngs ) { + result.add( fromAMap( latLng ) ); + } + return result; + } + + public static List< LatLonPoint > fromMogo( List< MogoLatLng > latLngs ) { + if ( latLngs == null ) { + return null; + } + List< LatLonPoint > result = new ArrayList<>( latLngs.size() ); + for ( MogoLatLng latLng : latLngs ) { + result.add( fromMogo( latLng ) ); + } + return result; + } + + + public static PoiSearch.SearchBound fromMogo( MogoSearchBound bound ) { + if ( bound == null ) { + return null; + } + if ( bound.getShape() == MogoSearchBound.SHAPE_BOUND ) { + return new PoiSearch.SearchBound( fromMogo( bound.getCenterPoint() ), bound.getRadiusInMeters(), bound.isDistanceSort() ); + } else if ( bound.getShape() == MogoSearchBound.SHAPE_POLYGON ) { + return new PoiSearch.SearchBound( fromMogo( bound.getPolyGonList() ) ); + } else if ( bound.getShape() == MogoSearchBound.SHAPE_RECTANGLE ) { + return new PoiSearch.SearchBound( fromMogo( bound.getLowerLeft() ), fromMogo( bound.getUpperRight() ) ); + } + return null; + } + + public static MogoPoiResult fromAMap( PoiResult result ) { + if ( result == null ) { + return null; + } + MogoPoiResult mogoPoiResult = new MogoPoiResult(); + if ( result.getPois() != null ) { + final List< PoiItem > poiItems = result.getPois(); + final ArrayList< MogoPoiItem > mogoPoiItems = new ArrayList<>( poiItems.size() ); + for ( PoiItem poiItem : poiItems ) { + mogoPoiItems.add( fromAMap( poiItem ) ); + } + mogoPoiResult.setPois( mogoPoiItems ); + } + return mogoPoiResult; + } + + public static MogoNaviInfo fromAMap( Context context, NaviInfo naviInfo ) { + if ( naviInfo == null ) { + return null; + } + MogoNaviInfo mogoNaviInfo = new MogoNaviInfo(); + mogoNaviInfo.setCurrentRoadName( naviInfo.getCurrentRoadName() ); + mogoNaviInfo.setCurrentSpeed( naviInfo.getCurrentSpeed() ); + mogoNaviInfo.setCurStepRetainDistance( naviInfo.getCurStepRetainDistance() ); + mogoNaviInfo.setCurStepRetainTime( naviInfo.getCurStepRetainTime() ); + mogoNaviInfo.setIconResId( IconTypeUtils.getResIdByIconType( context, naviInfo.getIconType() ) ); + mogoNaviInfo.setNextRoadName( naviInfo.getNextRoadName() ); + mogoNaviInfo.setPathRetainDistance( naviInfo.getPathRetainDistance() ); + mogoNaviInfo.setPathRetainTime( naviInfo.getPathRetainTime() ); + mogoNaviInfo.setCurrentSpeed( naviInfo.getLimitSpeed() ); + return mogoNaviInfo; + } + + public static MogoCongestionInfo fromAMap( AimLessModeCongestionInfo aimLessModeCongestionInfo ) { + if ( aimLessModeCongestionInfo == null ) { + return null; + } + MogoCongestionInfo congestionInfo = new MogoCongestionInfo(); + congestionInfo.setCongestionStatus( aimLessModeCongestionInfo.getCongestionStatus() ); + congestionInfo.setEventLat( aimLessModeCongestionInfo.getEventLat() ); + congestionInfo.setEventLon( aimLessModeCongestionInfo.getEventLon() ); + congestionInfo.setEventType( aimLessModeCongestionInfo.getEventType() ); + congestionInfo.setCongestionLinks( new ArrayList< MogoCongestionLink >() ); + congestionInfo.setLength( aimLessModeCongestionInfo.getLength() ); + congestionInfo.setRoadName( aimLessModeCongestionInfo.getRoadName() ); + congestionInfo.setTime( aimLessModeCongestionInfo.getTime() ); + if ( aimLessModeCongestionInfo.getAmapCongestionLinks() != null + && aimLessModeCongestionInfo.getAmapCongestionLinks().length != 0 ) { + for ( AMapCongestionLink amapCongestionLink : aimLessModeCongestionInfo.getAmapCongestionLinks() ) { + if ( amapCongestionLink == null ) { + continue; + } + MogoCongestionLink link = new MogoCongestionLink(); + link.setCongestionStatus( amapCongestionLink.getCongestionStatus() ); + if ( amapCongestionLink.getCoords() != null ) { + link.setCoords( new ArrayList< MogoLatLng >() ); + Iterator< NaviLatLng > iterator = amapCongestionLink.getCoords().iterator(); + while ( iterator.hasNext() ) { + NaviLatLng naviLatLng = iterator.next(); + if ( naviLatLng == null ) { + continue; + } + link.getCoords().add( new MogoLatLng( naviLatLng.getLatitude(), naviLatLng.getLongitude() ) ); + } + } + congestionInfo.getCongestionLinks().add( link ); + } + } + return congestionInfo; + } + + public static MogoTraffic fromAMap( AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos ) { + if ( aMapNaviTrafficFacilityInfos == null || aMapNaviTrafficFacilityInfos.length == 0 ) { + return null; + } + for ( AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo : aMapNaviTrafficFacilityInfos ) { + if ( aMapNaviTrafficFacilityInfo == null ) { + continue; + } + MogoTraffic traffic = new MogoTraffic( MogoTraffic.TYPE_AIM ); + traffic.setDistance( aMapNaviTrafficFacilityInfo.getDistance() ); + traffic.setSpeedLimit( aMapNaviTrafficFacilityInfo.getLimitSpeed() ); + traffic.setTrafficType( aMapNaviTrafficFacilityInfo.getBroadcastType() ); + traffic.setLat( aMapNaviTrafficFacilityInfo.latitude ); + traffic.setLon( aMapNaviTrafficFacilityInfo.longitude ); + return traffic; + } + return null; + } + + public static PolylineOptions fromMogo( MogoPolylineOptions options ) { + if ( options == null ) { + return null; + } + PolylineOptions target = new PolylineOptions(); + if ( options.getPoints() != null ) { + List< LatLng > points = new ArrayList<>(); + for ( MogoLatLng point : options.getPoints() ) { + points.add( fromMogo2( point ) ); + } + target.addAll( points ); + } + target.width( options.getWidth() ); + target.color( options.getColor() ); + target.zIndex( options.getWidth() ); + target.visible( options.isVisible() ); + target.geodesic( options.isGeodesic() ); + target.setDottedLine( options.isDottedLine() ); + target.useGradient( options.isGradient() ); + if ( options.getColorValues() != null ) { + target.colorValues( options.getColorValues() ); + } + target.transparency( options.getTransparency() ); + target.aboveMaskLayer( options.isAboveMaskLayer() ); + target.lineCapType( PolylineOptions.LineCapType.LineCapRound ); + target.lineJoinType( PolylineOptions.LineJoinType.LineJoinRound ); + target.setDottedLineType( PolylineOptions.DOTTEDLINE_TYPE_CIRCLE ); + return target; + } + + public static MogoLatLng fromAMap( LatLng latLng ) { + if ( latLng == null ) { + return null; + } + return new MogoLatLng( latLng.latitude, latLng.longitude ); + } + + public static MapCameraPosition fromAMap( CameraPosition position ) { + if ( position == null ) { + return null; + } + return new MapCameraPosition( fromAMap( position.target ), position.bearing, position.tilt, position.zoom ); + } } diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_bus.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_bus.png new file mode 100644 index 0000000000..66f73f4454 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_bus.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_car.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_car.png new file mode 100644 index 0000000000..b12b10c83f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_car.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_end.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_end.png new file mode 100644 index 0000000000..5503dc5a28 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_end.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_man.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_man.png new file mode 100644 index 0000000000..16842d5d12 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_man.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_ride.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_ride.png new file mode 100644 index 0000000000..2fa5633c59 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_ride.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_0_arrow.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_0_arrow.png new file mode 100644 index 0000000000..21793fea2b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_0_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_1_arrow.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_1_arrow.png new file mode 100644 index 0000000000..d7d832857f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_1_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_2_arrow.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_2_arrow.png new file mode 100644 index 0000000000..c1d019b4ae Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_2_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_3_arrow.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_3_arrow.png new file mode 100644 index 0000000000..b3318ad436 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_3_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_4_arrow.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_4_arrow.png new file mode 100644 index 0000000000..038e63f485 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_4_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_5_arrow.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_5_arrow.png new file mode 100644 index 0000000000..e15ce84e87 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_5_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_6_arrow.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_6_arrow.png new file mode 100644 index 0000000000..9f3540757a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_6_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_7_arrow.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_7_arrow.png new file mode 100644 index 0000000000..cef675f06f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_7_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_8_arrow.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_8_arrow.png new file mode 100644 index 0000000000..c4d67d38a4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_8_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_9_arrow.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_9_arrow.png new file mode 100644 index 0000000000..3c92f82f0d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_route_color_texture_9_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_start.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_start.png new file mode 100644 index 0000000000..cd716c8840 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_start.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/amap_through.png b/libraries/map-amap/src/main/res/drawable-ldpi/amap_through.png new file mode 100644 index 0000000000..e636b446c1 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/amap_through.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/app_icon.png b/libraries/map-amap/src/main/res/drawable-ldpi/app_icon.png new file mode 100644 index 0000000000..c97be4be12 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/app_icon.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/default_image.png b/libraries/map-amap/src/main/res/drawable-ldpi/default_image.png new file mode 100644 index 0000000000..fdc210cd25 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/default_image.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir1.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir1.png new file mode 100644 index 0000000000..fec3f4ec69 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir1.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir10.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir10.png new file mode 100644 index 0000000000..34c2228f6c Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir10.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir11.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir11.png new file mode 100644 index 0000000000..df9e8dc67c Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir11.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir12.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir12.png new file mode 100644 index 0000000000..a4ba8c22cb Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir12.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir13.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir13.png new file mode 100644 index 0000000000..39ad870c5f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir13.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir14.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir14.png new file mode 100644 index 0000000000..a3c1632562 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir14.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir15.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir15.png new file mode 100644 index 0000000000..c99fb65b94 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir15.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir16.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir16.png new file mode 100644 index 0000000000..86898c2144 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir16.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir2.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir2.png new file mode 100644 index 0000000000..750b6fbb7e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir2.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir3.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir3.png new file mode 100644 index 0000000000..8cbe886e81 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir3.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir4.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir4.png new file mode 100644 index 0000000000..cfe7d6c0fb Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir4.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir5.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir5.png new file mode 100644 index 0000000000..e465d5eec2 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir5.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir6.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir6.png new file mode 100644 index 0000000000..0d2f3c0360 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir6.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir7.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir7.png new file mode 100644 index 0000000000..e53c9ff451 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir7.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir8.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir8.png new file mode 100644 index 0000000000..edfdbe1df0 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir8.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir9.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir9.png new file mode 100644 index 0000000000..a762d0b74a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir9.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir_end.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir_end.png new file mode 100644 index 0000000000..f3cb78aed4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir_end.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir_start.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir_start.png new file mode 100644 index 0000000000..4d2a797823 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir_start.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/dir_station.png b/libraries/map-amap/src/main/res/drawable-ldpi/dir_station.png new file mode 100644 index 0000000000..2ed622283b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/dir_station.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_1.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_1.png new file mode 100644 index 0000000000..0fa0edb0a4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_1.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_10.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_10.png new file mode 100644 index 0000000000..797b106127 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_10.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_11.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_11.png new file mode 100644 index 0000000000..e54bbd6292 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_11.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_12.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_12.png new file mode 100644 index 0000000000..f93a673421 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_12.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_13.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_13.png new file mode 100644 index 0000000000..bf8d9bc3db Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_13.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_14.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_14.png new file mode 100644 index 0000000000..e7288ac5c2 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_14.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_15.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_15.png new file mode 100644 index 0000000000..9c0c2af8f4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_15.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_16.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_16.png new file mode 100644 index 0000000000..30cffd20e5 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_16.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_17.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_17.png new file mode 100644 index 0000000000..81ebaa35cd Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_17.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_18.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_18.png new file mode 100644 index 0000000000..8370408b15 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_18.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_19.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_19.png new file mode 100644 index 0000000000..da5648fb9c Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_19.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_2.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_2.png new file mode 100644 index 0000000000..851d6d878e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_2.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_20.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_20.png new file mode 100644 index 0000000000..79ffe11b10 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_20.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_21.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_21.png new file mode 100644 index 0000000000..9f80ca5181 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_21.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_22.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_22.png new file mode 100644 index 0000000000..403c5ea7e8 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_22.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_23.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_23.png new file mode 100644 index 0000000000..6e1b9f33b8 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_23.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_24.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_24.png new file mode 100644 index 0000000000..060b5e94f0 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_24.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_25.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_25.png new file mode 100644 index 0000000000..7a027897ce Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_25.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_26.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_26.png new file mode 100644 index 0000000000..6806d3457e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_26.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_27.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_27.png new file mode 100644 index 0000000000..dd1717bd6b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_27.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_28.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_28.png new file mode 100644 index 0000000000..239b379f3b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_28.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_4.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_4.png new file mode 100644 index 0000000000..5cf551b141 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_4.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_5.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_5.png new file mode 100644 index 0000000000..70ac563aa4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_5.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_50.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_50.png new file mode 100644 index 0000000000..4780ef7427 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_50.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_51.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_51.png new file mode 100644 index 0000000000..f6501640a1 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_51.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_52.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_52.png new file mode 100644 index 0000000000..7c8a880609 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_52.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_53.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_53.png new file mode 100644 index 0000000000..4cb5e21820 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_53.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_54.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_54.png new file mode 100644 index 0000000000..37289bbaaf Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_54.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_55.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_55.png new file mode 100644 index 0000000000..e8263cdc1b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_55.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_56.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_56.png new file mode 100644 index 0000000000..48b91385ad Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_56.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_57.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_57.png new file mode 100644 index 0000000000..080eaece28 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_57.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_58.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_58.png new file mode 100644 index 0000000000..7f7034ff9f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_58.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_59.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_59.png new file mode 100644 index 0000000000..735392d59d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_59.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_6.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_6.png new file mode 100644 index 0000000000..ff9757c869 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_6.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_60.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_60.png new file mode 100644 index 0000000000..98c94b3826 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_60.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_61.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_61.png new file mode 100644 index 0000000000..a924085ef8 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_61.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_62.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_62.png new file mode 100644 index 0000000000..c20542f34f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_62.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_63.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_63.png new file mode 100644 index 0000000000..d408fe0153 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_63.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_64.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_64.png new file mode 100644 index 0000000000..5a9af68c32 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_64.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_65.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_65.png new file mode 100644 index 0000000000..57a7454b4f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_65.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_66.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_66.png new file mode 100644 index 0000000000..c471bf466a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_66.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_67.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_67.png new file mode 100644 index 0000000000..22e6178738 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_67.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_68.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_68.png new file mode 100644 index 0000000000..a782cffbd9 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_68.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_69.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_69.png new file mode 100644 index 0000000000..a1545ef55f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_69.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_7.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_7.png new file mode 100644 index 0000000000..b4a6465ce0 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_7.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_8.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_8.png new file mode 100644 index 0000000000..d19f036aa9 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_8.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_9.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_9.png new file mode 100644 index 0000000000..a2b07ad3d7 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_9.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_endpoint.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_endpoint.png new file mode 100644 index 0000000000..a1716599df Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_endpoint.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_refresh.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_refresh.png new file mode 100644 index 0000000000..d86c3f8024 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_refresh.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/ic_snapshot_ph.png b/libraries/map-amap/src/main/res/drawable-ldpi/ic_snapshot_ph.png new file mode 100644 index 0000000000..281f1bb163 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/ic_snapshot_ph.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/join_checkbox_bg.png b/libraries/map-amap/src/main/res/drawable-ldpi/join_checkbox_bg.png new file mode 100644 index 0000000000..89d00803c5 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/join_checkbox_bg.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/live_exit.png b/libraries/map-amap/src/main/res/drawable-ldpi/live_exit.png new file mode 100644 index 0000000000..7d9b50f159 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/live_exit.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/location_city_image.png b/libraries/map-amap/src/main/res/drawable-ldpi/location_city_image.png new file mode 100644 index 0000000000..ce5515c529 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/location_city_image.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_left_page_up_normal.png b/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_left_page_up_normal.png new file mode 100644 index 0000000000..9c1a2a4aea Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_left_page_up_normal.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_left_page_up_press.png b/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_left_page_up_press.png new file mode 100644 index 0000000000..d927b18877 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_left_page_up_press.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_right_page_up_normal.png b/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_right_page_up_normal.png new file mode 100644 index 0000000000..dda526f475 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_right_page_up_normal.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_right_page_up_press.png b/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_right_page_up_press.png new file mode 100644 index 0000000000..2289209d9a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/main_solid_right_page_up_press.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/mainpage_location_img.png b/libraries/map-amap/src/main/res/drawable-ldpi/mainpage_location_img.png new file mode 100644 index 0000000000..7a463ac3ab Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/mainpage_location_img.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/map_api_ic_current_location2.png b/libraries/map-amap/src/main/res/drawable-ldpi/map_api_ic_current_location2.png new file mode 100644 index 0000000000..5d2d79c7e5 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/map_api_ic_current_location2.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/map_location_normal.png b/libraries/map-amap/src/main/res/drawable-ldpi/map_location_normal.png new file mode 100644 index 0000000000..53f5b5a14a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/map_location_normal.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/map_location_press.png b/libraries/map-amap/src/main/res/drawable-ldpi/map_location_press.png new file mode 100644 index 0000000000..e3e430c8d6 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/map_location_press.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/not_join_checkbox_bg.png b/libraries/map-amap/src/main/res/drawable-ldpi/not_join_checkbox_bg.png new file mode 100644 index 0000000000..663addd255 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/not_join_checkbox_bg.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/public_arrow_back_iv.png b/libraries/map-amap/src/main/res/drawable-ldpi/public_arrow_back_iv.png new file mode 100644 index 0000000000..cd7159e219 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/public_arrow_back_iv.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/search_information_normal.png b/libraries/map-amap/src/main/res/drawable-ldpi/search_information_normal.png new file mode 100644 index 0000000000..69529ef0bd Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/search_information_normal.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/search_information_press.png b/libraries/map-amap/src/main/res/drawable-ldpi/search_information_press.png new file mode 100644 index 0000000000..8338cc95ae Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/search_information_press.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_10.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_10.png new file mode 100644 index 0000000000..629e98359d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_10.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_11.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_11.png new file mode 100644 index 0000000000..c0d6528e63 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_11.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_12.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_12.png new file mode 100644 index 0000000000..c14ec9a985 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_12.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_13.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_13.png new file mode 100644 index 0000000000..71bc66ca60 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_13.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_14.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_14.png new file mode 100644 index 0000000000..15e798dcce Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_14.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_15.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_15.png new file mode 100644 index 0000000000..a69e9437f3 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_15.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_16.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_16.png new file mode 100644 index 0000000000..ff948797b4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_16.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_17.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_17.png new file mode 100644 index 0000000000..8fc3e5d0df Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_17.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_20.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_20.png new file mode 100644 index 0000000000..b6cf203416 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_20.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_21.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_21.png new file mode 100644 index 0000000000..0c55bebb7a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_21.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_22.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_22.png new file mode 100644 index 0000000000..73f6c6c7ca Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_22.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_23.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_23.png new file mode 100644 index 0000000000..fb4a106126 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_23.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_24.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_24.png new file mode 100644 index 0000000000..a40251e6af Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_24.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_25.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_25.png new file mode 100644 index 0000000000..dba53847bb Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_25.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_26.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_26.png new file mode 100644 index 0000000000..c2ad298a10 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_26.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_27.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_27.png new file mode 100644 index 0000000000..266e5a9a6b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_27.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_28.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_28.png new file mode 100644 index 0000000000..15259c17eb Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_28.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_30.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_30.png new file mode 100644 index 0000000000..bc76d71ab9 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_30.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_31.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_31.png new file mode 100644 index 0000000000..5e8e8d31fb Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_31.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_32.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_32.png new file mode 100644 index 0000000000..52e2e6a540 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_32.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_33.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_33.png new file mode 100644 index 0000000000..357de360f4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_33.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_34.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_34.png new file mode 100644 index 0000000000..ef5a9d75b2 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_34.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_35.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_35.png new file mode 100644 index 0000000000..9c0d6b2058 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_35.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_36.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_36.png new file mode 100644 index 0000000000..f99d780e06 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_36.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_37.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_37.png new file mode 100644 index 0000000000..17fff66f7b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_37.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_38.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_38.png new file mode 100644 index 0000000000..d4464587af Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_38.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_39.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_39.png new file mode 100644 index 0000000000..a7db692ecc Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_39.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_40.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_40.png new file mode 100644 index 0000000000..5cd1176c4d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_40.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_41.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_41.png new file mode 100644 index 0000000000..89c97b5dc8 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_41.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_42.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_42.png new file mode 100644 index 0000000000..d76fa3a7c6 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_42.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_43.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_43.png new file mode 100644 index 0000000000..15ca9088f1 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_43.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_44.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_44.png new file mode 100644 index 0000000000..fe01e04472 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_44.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_68.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_68.png new file mode 100644 index 0000000000..0d57b42290 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_68.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_84.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_84.png new file mode 100644 index 0000000000..99bdea2e1e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_84.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/tc_85.png b/libraries/map-amap/src/main/res/drawable-ldpi/tc_85.png new file mode 100644 index 0000000000..e85921c9c3 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/tc_85.png differ diff --git a/libraries/map-amap/src/main/res/drawable-ldpi/video_loading_img.png b/libraries/map-amap/src/main/res/drawable-ldpi/video_loading_img.png new file mode 100644 index 0000000000..48be2bdd18 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-ldpi/video_loading_img.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_bus.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_bus.png new file mode 100644 index 0000000000..66f73f4454 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_bus.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_car.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_car.png new file mode 100644 index 0000000000..b12b10c83f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_car.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_end.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_end.png new file mode 100644 index 0000000000..5503dc5a28 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_end.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_man.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_man.png new file mode 100644 index 0000000000..16842d5d12 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_man.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_ride.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_ride.png new file mode 100644 index 0000000000..2fa5633c59 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_ride.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_0_arrow.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_0_arrow.png new file mode 100644 index 0000000000..21793fea2b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_0_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_1_arrow.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_1_arrow.png new file mode 100644 index 0000000000..d7d832857f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_1_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_2_arrow.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_2_arrow.png new file mode 100644 index 0000000000..c1d019b4ae Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_2_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_3_arrow.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_3_arrow.png new file mode 100644 index 0000000000..b3318ad436 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_3_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_4_arrow.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_4_arrow.png new file mode 100644 index 0000000000..038e63f485 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_4_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_5_arrow.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_5_arrow.png new file mode 100644 index 0000000000..e15ce84e87 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_5_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_6_arrow.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_6_arrow.png new file mode 100644 index 0000000000..9f3540757a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_6_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_7_arrow.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_7_arrow.png new file mode 100644 index 0000000000..cef675f06f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_7_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_8_arrow.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_8_arrow.png new file mode 100644 index 0000000000..c4d67d38a4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_8_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_9_arrow.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_9_arrow.png new file mode 100644 index 0000000000..3c92f82f0d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_route_color_texture_9_arrow.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_start.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_start.png new file mode 100644 index 0000000000..cd716c8840 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_start.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/amap_through.png b/libraries/map-amap/src/main/res/drawable-mdpi/amap_through.png new file mode 100644 index 0000000000..e636b446c1 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/amap_through.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/app_icon.png b/libraries/map-amap/src/main/res/drawable-mdpi/app_icon.png new file mode 100644 index 0000000000..c97be4be12 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/app_icon.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/default_image.png b/libraries/map-amap/src/main/res/drawable-mdpi/default_image.png new file mode 100644 index 0000000000..fdc210cd25 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/default_image.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir1.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir1.png new file mode 100644 index 0000000000..fec3f4ec69 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir1.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir10.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir10.png new file mode 100644 index 0000000000..34c2228f6c Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir10.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir11.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir11.png new file mode 100644 index 0000000000..df9e8dc67c Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir11.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir12.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir12.png new file mode 100644 index 0000000000..a4ba8c22cb Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir12.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir13.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir13.png new file mode 100644 index 0000000000..39ad870c5f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir13.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir14.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir14.png new file mode 100644 index 0000000000..a3c1632562 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir14.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir15.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir15.png new file mode 100644 index 0000000000..c99fb65b94 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir15.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir16.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir16.png new file mode 100644 index 0000000000..86898c2144 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir16.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir2.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir2.png new file mode 100644 index 0000000000..750b6fbb7e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir2.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir3.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir3.png new file mode 100644 index 0000000000..8cbe886e81 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir3.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir4.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir4.png new file mode 100644 index 0000000000..cfe7d6c0fb Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir4.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir5.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir5.png new file mode 100644 index 0000000000..e465d5eec2 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir5.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir6.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir6.png new file mode 100644 index 0000000000..0d2f3c0360 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir6.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir7.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir7.png new file mode 100644 index 0000000000..e53c9ff451 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir7.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir8.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir8.png new file mode 100644 index 0000000000..edfdbe1df0 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir8.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir9.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir9.png new file mode 100644 index 0000000000..a762d0b74a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir9.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir_end.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir_end.png new file mode 100644 index 0000000000..f3cb78aed4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir_end.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir_start.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir_start.png new file mode 100644 index 0000000000..4d2a797823 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir_start.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/dir_station.png b/libraries/map-amap/src/main/res/drawable-mdpi/dir_station.png new file mode 100644 index 0000000000..2ed622283b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/dir_station.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_1.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_1.png new file mode 100644 index 0000000000..0fa0edb0a4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_1.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_10.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_10.png new file mode 100644 index 0000000000..797b106127 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_10.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_11.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_11.png new file mode 100644 index 0000000000..e54bbd6292 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_11.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_12.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_12.png new file mode 100644 index 0000000000..f93a673421 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_12.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_13.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_13.png new file mode 100644 index 0000000000..bf8d9bc3db Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_13.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_14.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_14.png new file mode 100644 index 0000000000..e7288ac5c2 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_14.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_15.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_15.png new file mode 100644 index 0000000000..9c0c2af8f4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_15.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_16.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_16.png new file mode 100644 index 0000000000..30cffd20e5 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_16.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_17.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_17.png new file mode 100644 index 0000000000..81ebaa35cd Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_17.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_18.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_18.png new file mode 100644 index 0000000000..8370408b15 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_18.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_19.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_19.png new file mode 100644 index 0000000000..da5648fb9c Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_19.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_2.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_2.png new file mode 100644 index 0000000000..851d6d878e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_2.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_20.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_20.png new file mode 100644 index 0000000000..79ffe11b10 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_20.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_21.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_21.png new file mode 100644 index 0000000000..9f80ca5181 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_21.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_22.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_22.png new file mode 100644 index 0000000000..403c5ea7e8 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_22.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_23.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_23.png new file mode 100644 index 0000000000..6e1b9f33b8 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_23.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_24.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_24.png new file mode 100644 index 0000000000..060b5e94f0 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_24.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_25.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_25.png new file mode 100644 index 0000000000..7a027897ce Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_25.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_26.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_26.png new file mode 100644 index 0000000000..6806d3457e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_26.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_27.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_27.png new file mode 100644 index 0000000000..dd1717bd6b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_27.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_28.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_28.png new file mode 100644 index 0000000000..239b379f3b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_28.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_4.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_4.png new file mode 100644 index 0000000000..5cf551b141 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_4.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_5.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_5.png new file mode 100644 index 0000000000..70ac563aa4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_5.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_50.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_50.png new file mode 100644 index 0000000000..4780ef7427 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_50.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_51.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_51.png new file mode 100644 index 0000000000..f6501640a1 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_51.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_52.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_52.png new file mode 100644 index 0000000000..7c8a880609 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_52.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_53.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_53.png new file mode 100644 index 0000000000..4cb5e21820 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_53.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_54.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_54.png new file mode 100644 index 0000000000..37289bbaaf Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_54.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_55.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_55.png new file mode 100644 index 0000000000..e8263cdc1b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_55.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_56.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_56.png new file mode 100644 index 0000000000..48b91385ad Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_56.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_57.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_57.png new file mode 100644 index 0000000000..080eaece28 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_57.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_58.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_58.png new file mode 100644 index 0000000000..7f7034ff9f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_58.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_59.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_59.png new file mode 100644 index 0000000000..735392d59d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_59.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_6.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_6.png new file mode 100644 index 0000000000..ff9757c869 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_6.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_60.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_60.png new file mode 100644 index 0000000000..98c94b3826 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_60.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_61.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_61.png new file mode 100644 index 0000000000..a924085ef8 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_61.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_62.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_62.png new file mode 100644 index 0000000000..c20542f34f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_62.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_63.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_63.png new file mode 100644 index 0000000000..d408fe0153 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_63.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_64.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_64.png new file mode 100644 index 0000000000..5a9af68c32 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_64.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_65.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_65.png new file mode 100644 index 0000000000..57a7454b4f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_65.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_66.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_66.png new file mode 100644 index 0000000000..c471bf466a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_66.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_67.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_67.png new file mode 100644 index 0000000000..22e6178738 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_67.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_68.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_68.png new file mode 100644 index 0000000000..a782cffbd9 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_68.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_69.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_69.png new file mode 100644 index 0000000000..a1545ef55f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_69.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_7.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_7.png new file mode 100644 index 0000000000..b4a6465ce0 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_7.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_8.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_8.png new file mode 100644 index 0000000000..d19f036aa9 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_8.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_9.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_9.png new file mode 100644 index 0000000000..a2b07ad3d7 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_9.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_endpoint.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_endpoint.png new file mode 100644 index 0000000000..a1716599df Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_endpoint.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_refresh.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_refresh.png new file mode 100644 index 0000000000..d86c3f8024 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_refresh.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/ic_snapshot_ph.png b/libraries/map-amap/src/main/res/drawable-mdpi/ic_snapshot_ph.png new file mode 100644 index 0000000000..281f1bb163 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/ic_snapshot_ph.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/join_checkbox_bg.png b/libraries/map-amap/src/main/res/drawable-mdpi/join_checkbox_bg.png new file mode 100644 index 0000000000..89d00803c5 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/join_checkbox_bg.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/live_exit.png b/libraries/map-amap/src/main/res/drawable-mdpi/live_exit.png new file mode 100644 index 0000000000..7d9b50f159 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/live_exit.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/location_city_image.png b/libraries/map-amap/src/main/res/drawable-mdpi/location_city_image.png new file mode 100644 index 0000000000..ce5515c529 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/location_city_image.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_left_page_up_normal.png b/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_left_page_up_normal.png new file mode 100644 index 0000000000..9c1a2a4aea Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_left_page_up_normal.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_left_page_up_press.png b/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_left_page_up_press.png new file mode 100644 index 0000000000..d927b18877 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_left_page_up_press.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_right_page_up_normal.png b/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_right_page_up_normal.png new file mode 100644 index 0000000000..dda526f475 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_right_page_up_normal.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_right_page_up_press.png b/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_right_page_up_press.png new file mode 100644 index 0000000000..2289209d9a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/main_solid_right_page_up_press.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/mainpage_location_img.png b/libraries/map-amap/src/main/res/drawable-mdpi/mainpage_location_img.png new file mode 100644 index 0000000000..7a463ac3ab Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/mainpage_location_img.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/map_api_ic_current_location2.png b/libraries/map-amap/src/main/res/drawable-mdpi/map_api_ic_current_location2.png new file mode 100644 index 0000000000..5d2d79c7e5 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/map_api_ic_current_location2.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/map_location_normal.png b/libraries/map-amap/src/main/res/drawable-mdpi/map_location_normal.png new file mode 100644 index 0000000000..53f5b5a14a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/map_location_normal.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/map_location_press.png b/libraries/map-amap/src/main/res/drawable-mdpi/map_location_press.png new file mode 100644 index 0000000000..e3e430c8d6 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/map_location_press.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/not_join_checkbox_bg.png b/libraries/map-amap/src/main/res/drawable-mdpi/not_join_checkbox_bg.png new file mode 100644 index 0000000000..663addd255 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/not_join_checkbox_bg.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/public_arrow_back_iv.png b/libraries/map-amap/src/main/res/drawable-mdpi/public_arrow_back_iv.png new file mode 100644 index 0000000000..cd7159e219 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/public_arrow_back_iv.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/search_information_normal.png b/libraries/map-amap/src/main/res/drawable-mdpi/search_information_normal.png new file mode 100644 index 0000000000..69529ef0bd Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/search_information_normal.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/search_information_press.png b/libraries/map-amap/src/main/res/drawable-mdpi/search_information_press.png new file mode 100644 index 0000000000..8338cc95ae Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/search_information_press.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_10.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_10.png new file mode 100644 index 0000000000..629e98359d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_10.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_11.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_11.png new file mode 100644 index 0000000000..c0d6528e63 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_11.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_12.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_12.png new file mode 100644 index 0000000000..c14ec9a985 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_12.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_13.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_13.png new file mode 100644 index 0000000000..71bc66ca60 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_13.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_14.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_14.png new file mode 100644 index 0000000000..15e798dcce Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_14.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_15.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_15.png new file mode 100644 index 0000000000..a69e9437f3 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_15.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_16.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_16.png new file mode 100644 index 0000000000..ff948797b4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_16.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_17.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_17.png new file mode 100644 index 0000000000..8fc3e5d0df Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_17.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_20.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_20.png new file mode 100644 index 0000000000..b6cf203416 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_20.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_21.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_21.png new file mode 100644 index 0000000000..0c55bebb7a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_21.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_22.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_22.png new file mode 100644 index 0000000000..73f6c6c7ca Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_22.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_23.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_23.png new file mode 100644 index 0000000000..fb4a106126 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_23.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_24.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_24.png new file mode 100644 index 0000000000..a40251e6af Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_24.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_25.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_25.png new file mode 100644 index 0000000000..dba53847bb Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_25.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_26.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_26.png new file mode 100644 index 0000000000..c2ad298a10 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_26.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_27.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_27.png new file mode 100644 index 0000000000..266e5a9a6b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_27.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_28.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_28.png new file mode 100644 index 0000000000..15259c17eb Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_28.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_30.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_30.png new file mode 100644 index 0000000000..bc76d71ab9 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_30.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_31.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_31.png new file mode 100644 index 0000000000..5e8e8d31fb Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_31.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_32.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_32.png new file mode 100644 index 0000000000..52e2e6a540 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_32.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_33.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_33.png new file mode 100644 index 0000000000..357de360f4 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_33.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_34.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_34.png new file mode 100644 index 0000000000..ef5a9d75b2 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_34.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_35.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_35.png new file mode 100644 index 0000000000..9c0d6b2058 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_35.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_36.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_36.png new file mode 100644 index 0000000000..f99d780e06 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_36.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_37.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_37.png new file mode 100644 index 0000000000..17fff66f7b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_37.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_38.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_38.png new file mode 100644 index 0000000000..d4464587af Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_38.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_39.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_39.png new file mode 100644 index 0000000000..a7db692ecc Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_39.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_40.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_40.png new file mode 100644 index 0000000000..5cd1176c4d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_40.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_41.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_41.png new file mode 100644 index 0000000000..89c97b5dc8 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_41.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_42.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_42.png new file mode 100644 index 0000000000..d76fa3a7c6 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_42.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_43.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_43.png new file mode 100644 index 0000000000..15ca9088f1 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_43.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_44.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_44.png new file mode 100644 index 0000000000..fe01e04472 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_44.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_68.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_68.png new file mode 100644 index 0000000000..0d57b42290 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_68.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_84.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_84.png new file mode 100644 index 0000000000..99bdea2e1e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_84.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/tc_85.png b/libraries/map-amap/src/main/res/drawable-mdpi/tc_85.png new file mode 100644 index 0000000000..e85921c9c3 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/tc_85.png differ diff --git a/libraries/map-amap/src/main/res/drawable-mdpi/video_loading_img.png b/libraries/map-amap/src/main/res/drawable-mdpi/video_loading_img.png new file mode 100644 index 0000000000..48be2bdd18 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-mdpi/video_loading_img.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi-1920x1000/map_api_ic_current_location2.png b/libraries/map-amap/src/main/res/drawable-xhdpi-1920x1000/map_api_ic_current_location2.png new file mode 100644 index 0000000000..06fb9a934e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi-1920x1000/map_api_ic_current_location2.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_1.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_1.png new file mode 100755 index 0000000000..5a4c2cf96e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_1.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_10.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_10.png new file mode 100755 index 0000000000..5a05ce6474 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_10.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_11.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_11.png new file mode 100755 index 0000000000..8d8a894b58 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_11.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_12.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_12.png new file mode 100755 index 0000000000..96ffe793f8 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_12.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_13.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_13.png new file mode 100755 index 0000000000..4cfbae387d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_13.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_14.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_14.png new file mode 100755 index 0000000000..77d51fe649 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_14.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_15.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_15.png new file mode 100755 index 0000000000..b0f50cc894 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_15.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_16.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_16.png new file mode 100755 index 0000000000..bb21c76be1 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_16.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_17.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_17.png new file mode 100755 index 0000000000..eb9cfc2cdd Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_17.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_18.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_18.png new file mode 100755 index 0000000000..061114de81 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_18.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_19.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_19.png new file mode 100755 index 0000000000..bf4793327c Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_19.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_2.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_2.png new file mode 100755 index 0000000000..eb59de2d41 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_2.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_20.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_20.png new file mode 100755 index 0000000000..e8e6e92b49 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_20.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_21.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_21.png new file mode 100755 index 0000000000..3f8192d710 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_21.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_22.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_22.png new file mode 100755 index 0000000000..d479431b73 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_22.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_23.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_23.png new file mode 100755 index 0000000000..981a89f1a3 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_23.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_24.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_24.png new file mode 100755 index 0000000000..6d05927994 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_24.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_25.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_25.png new file mode 100755 index 0000000000..69df7c1534 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_25.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_26.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_26.png new file mode 100755 index 0000000000..29c3d23eff Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_26.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_27.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_27.png new file mode 100755 index 0000000000..611f3b41fb Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_27.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_28.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_28.png new file mode 100755 index 0000000000..0bdebdd05d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_28.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_3.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_3.png new file mode 100755 index 0000000000..e9d338aa96 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_3.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_4.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_4.png new file mode 100755 index 0000000000..353e5049b8 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_4.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_5.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_5.png new file mode 100755 index 0000000000..2b938c892e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_5.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_50.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_50.png new file mode 100755 index 0000000000..2902206da5 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_50.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_51.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_51.png new file mode 100755 index 0000000000..94db18a7f0 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_51.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_52.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_52.png new file mode 100755 index 0000000000..74e434228a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_52.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_53.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_53.png new file mode 100755 index 0000000000..cd1cfd42f7 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_53.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_54.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_54.png new file mode 100755 index 0000000000..adc0bbbbb3 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_54.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_55.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_55.png new file mode 100755 index 0000000000..3d63020dd2 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_55.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_56.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_56.png new file mode 100755 index 0000000000..a4dd04c61a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_56.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_57.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_57.png new file mode 100755 index 0000000000..9bd9e6945a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_57.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_58.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_58.png new file mode 100755 index 0000000000..89dd67242a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_58.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_59.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_59.png new file mode 100755 index 0000000000..e1bf5acd56 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_59.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_6.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_6.png new file mode 100755 index 0000000000..089222b492 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_6.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_60.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_60.png new file mode 100755 index 0000000000..5c797cfbf2 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_60.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_61.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_61.png new file mode 100755 index 0000000000..eddba707ef Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_61.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_62.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_62.png new file mode 100755 index 0000000000..db1ad2eeb7 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_62.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_63.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_63.png new file mode 100755 index 0000000000..957d08b307 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_63.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_64.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_64.png new file mode 100755 index 0000000000..3bcc77650a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_64.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_65.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_65.png new file mode 100755 index 0000000000..47897888a0 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_65.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_66.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_66.png new file mode 100755 index 0000000000..727505beb9 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_66.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_67.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_67.png new file mode 100755 index 0000000000..b18126a2f0 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_67.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_68.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_68.png new file mode 100755 index 0000000000..329995bd2f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_68.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_69.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_69.png new file mode 100755 index 0000000000..63d1ccd728 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_69.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_7.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_7.png new file mode 100755 index 0000000000..8257b5dfe3 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_7.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_8.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_8.png new file mode 100755 index 0000000000..7c29ae8f99 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_8.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_9.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_9.png new file mode 100755 index 0000000000..a348269ccc Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_9.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/ic_endpoint.png b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_endpoint.png new file mode 100644 index 0000000000..f178056730 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/ic_endpoint.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/map_api_ic_current_location2.png b/libraries/map-amap/src/main/res/drawable-xhdpi/map_api_ic_current_location2.png new file mode 100644 index 0000000000..c24c56f3db Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/map_api_ic_current_location2.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_10.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_10.png new file mode 100755 index 0000000000..bbc15d056d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_10.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_11.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_11.png new file mode 100755 index 0000000000..316f5e1b96 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_11.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_12.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_12.png new file mode 100755 index 0000000000..8e18625e6d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_12.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_13.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_13.png new file mode 100755 index 0000000000..903dff86ed Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_13.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_14.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_14.png new file mode 100755 index 0000000000..cd95173633 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_14.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_15.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_15.png new file mode 100755 index 0000000000..8bc4f5247d Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_15.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_16.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_16.png new file mode 100755 index 0000000000..7b9b08ebf2 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_16.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_17.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_17.png new file mode 100755 index 0000000000..5a1f932024 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_17.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_20.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_20.png new file mode 100755 index 0000000000..2d4462266e Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_20.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_21.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_21.png new file mode 100755 index 0000000000..7a950926ce Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_21.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_22.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_22.png new file mode 100755 index 0000000000..09b1272ce6 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_22.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_23.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_23.png new file mode 100755 index 0000000000..4e52213d57 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_23.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_24.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_24.png new file mode 100755 index 0000000000..d9afd535e5 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_24.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_25.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_25.png new file mode 100755 index 0000000000..70a25f3c25 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_25.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_26.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_26.png new file mode 100755 index 0000000000..d87fe0ba59 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_26.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_27.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_27.png new file mode 100755 index 0000000000..28afebb493 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_27.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_28.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_28.png new file mode 100755 index 0000000000..5c23e754e6 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_28.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_30.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_30.png new file mode 100755 index 0000000000..6593326f29 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_30.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_31.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_31.png new file mode 100755 index 0000000000..3bfa5983b6 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_31.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_32.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_32.png new file mode 100755 index 0000000000..53fa3dc1b2 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_32.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_33.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_33.png new file mode 100755 index 0000000000..e9a51bb3f1 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_33.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_34.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_34.png new file mode 100755 index 0000000000..c033de20cc Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_34.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_35.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_35.png new file mode 100755 index 0000000000..78c0a884b5 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_35.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_36.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_36.png new file mode 100755 index 0000000000..9d2d6889c9 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_36.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_37.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_37.png new file mode 100755 index 0000000000..45b1420b8a Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_37.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_38.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_38.png new file mode 100755 index 0000000000..e716d63c69 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_38.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_39.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_39.png new file mode 100755 index 0000000000..973a163dc9 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_39.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_40.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_40.png new file mode 100755 index 0000000000..10a7dc6995 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_40.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_41.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_41.png new file mode 100755 index 0000000000..89e9415071 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_41.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_42.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_42.png new file mode 100755 index 0000000000..2716e1a458 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_42.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_43.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_43.png new file mode 100755 index 0000000000..7ac8809a8b Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_43.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_44.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_44.png new file mode 100755 index 0000000000..0c4daba210 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_44.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_68.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_68.png new file mode 100755 index 0000000000..9763518122 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_68.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_84.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_84.png new file mode 100755 index 0000000000..24a6ef2e82 Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_84.png differ diff --git a/libraries/map-amap/src/main/res/drawable-xhdpi/tc_85.png b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_85.png new file mode 100755 index 0000000000..91e3cb0e8f Binary files /dev/null and b/libraries/map-amap/src/main/res/drawable-xhdpi/tc_85.png differ diff --git a/libraries/map-amap/src/main/res/values-ldpi/dimens.xml b/libraries/map-amap/src/main/res/values-ldpi/dimens.xml new file mode 100644 index 0000000000..242c78ec72 --- /dev/null +++ b/libraries/map-amap/src/main/res/values-ldpi/dimens.xml @@ -0,0 +1,4 @@ + + + 40px + \ No newline at end of file diff --git a/libraries/map-amap/src/main/res/values/dimens.xml b/libraries/map-amap/src/main/res/values/dimens.xml new file mode 100644 index 0000000000..e8bccfa287 --- /dev/null +++ b/libraries/map-amap/src/main/res/values/dimens.xml @@ -0,0 +1,4 @@ + + + 60px + \ No newline at end of file diff --git a/libraries/map-amap/src/main/res/values/strings.xml b/libraries/map-amap/src/main/res/values/strings.xml new file mode 100644 index 0000000000..63a33e31ae --- /dev/null +++ b/libraries/map-amap/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + map-amap + diff --git a/libraries/map-autonavi/.gitignore b/libraries/map-autonavi/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/libraries/map-autonavi/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/libraries/map-autonavi/build.gradle b/libraries/map-autonavi/build.gradle new file mode 100644 index 0000000000..fe07d63360 --- /dev/null +++ b/libraries/map-autonavi/build.gradle @@ -0,0 +1,47 @@ +apply plugin: 'com.android.library' + +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") + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility 1.8 + targetCompatibility 1.8 + } +} + +dependencies { + implementation fileTree(dir: "libs", include: ["*.jar"]) + if (Boolean.valueOf(RELEASE)) { + implementation rootProject.ext.dependencies.mogoutils + implementation rootProject.ext.dependencies.mogomapapi + implementation rootProject.ext.dependencies.mogocommons + implementation rootProject.ext.dependencies.mogomapapi + implementation rootProject.ext.dependencies.mapamap + } else { + implementation project(':foudations:mogo-utils') + implementation project(':libraries:mogo-map-api') + implementation project(':foudations:mogo-commons') + implementation project(':services:mogo-service-api') + implementation project(':libraries:map-amap') + + } +} + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() \ No newline at end of file diff --git a/libraries/map-autonavi/consumer-rules.pro b/libraries/map-autonavi/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libraries/map-autonavi/gradle.properties b/libraries/map-autonavi/gradle.properties new file mode 100644 index 0000000000..b57696e52a --- /dev/null +++ b/libraries/map-autonavi/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.map +POM_ARTIFACT_ID=map-autonavi +VERSION_CODE=1 \ No newline at end of file diff --git a/libraries/map-autonavi/proguard-rules.pro b/libraries/map-autonavi/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/libraries/map-autonavi/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/libraries/map-autonavi/src/main/AndroidManifest.xml b/libraries/map-autonavi/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..74341ccd56 --- /dev/null +++ b/libraries/map-autonavi/src/main/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/AutoNaviClient.java b/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/AutoNaviClient.java new file mode 100644 index 0000000000..9a8e553254 --- /dev/null +++ b/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/AutoNaviClient.java @@ -0,0 +1,230 @@ +package com.mogo.map.impl.automap.navi; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Rect; +import android.location.Location; + +import com.mogo.map.MogoLatLng; +import com.mogo.map.impl.amap.navi.NaviClient; +import com.mogo.map.navi.IMogoCarLocationChangedListener2; +import com.mogo.map.navi.IMogoNavi; +import com.mogo.map.navi.MogoCalculatePath; +import com.mogo.map.navi.MogoNaviConfig; +import com.mogo.map.navi.OnCalculatePathItemClickInteraction; +import com.mogo.utils.logger.Logger; + +import java.util.List; + +/** + * @author congtaowang + * @since 2020/6/2 + *

+ * 使用高德车机版导航 + */ +public class AutoNaviClient implements IMogoNavi { + + private static final String TAG = "NaviClient"; + + public static final String ACTION_AUTO_MAP = "AUTONAVI_STANDARD_BROADCAST_RECV"; + + public static final String KEY_TYPE = "KEY_TYPE"; + public static final String SOURCE_APP = "SOURCE_APP"; + public static final String LAT = "LAT"; + public static final String LON = "LON"; + public static final String ENTRY_LAT = "ENTRY_LAT"; + public static final String ENTRY_LON = "ENTRY_LON"; + public static final String DEV = "DEV"; // (int)是否偏移(0:lat 和 lon 是已经加密后的,不需要国测加密; 1:需要国测加密) + + /** + * (必填)(int)导航方式 + * =1(避免收费) + * =2(多策略算路) + * =3 (不走高速) + * =4(躲避拥堵) + * =5(不走高速且避免收费) + * =6(不走高速且躲避拥堵) + * =7(躲避收费且躲避拥堵) + * =8(不走高速躲避收费和拥堵) + * =20 (高速优先) + * =24(高速优先且躲避拥堵) + * =-1(地图内部设置默认规则) + */ + public static final String STYLE = "STYLE"; + + private static volatile AutoNaviClient sInstance; + private final Context mContext; + + private AutoNaviClient( Context context ) { + mContext = context; + } + + public static AutoNaviClient getInstance( Context context ) { + if ( sInstance == null ) { + synchronized ( AutoNaviClient.class ) { + if ( sInstance == null ) { + sInstance = new AutoNaviClient( context ); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + @Override + + public void naviTo( MogoLatLng endPoint ) { + Intent intent = new Intent(); + intent.putExtra( KEY_TYPE, 10038 ); + intent.putExtra( LAT, endPoint.lat ); + intent.putExtra( LON, endPoint.lon ); +// intent.putExtra( ENTRY_LAT, endPoint.lat ); +// intent.putExtra( ENTRY_LON, endPoint.lon ); + intent.putExtra( DEV, 0 ); + intent.putExtra( STYLE, -1 ); + intent.putExtra( SOURCE_APP, "Third App" ); + sendByIntent( intent ); + } + + @Override + public void naviTo( MogoLatLng endPoint, MogoNaviConfig config ) { + naviTo( endPoint ); + } + + @Override + public void naviTo( MogoLatLng endPoint, List< MogoLatLng > wayPoints ) { + naviTo( endPoint ); + } + + @Override + public void naviTo( MogoLatLng endPoint, List< MogoLatLng > wayPoints, MogoNaviConfig config ) { + naviTo( endPoint ); + } + + @Override + public void reCalculateRoute( MogoNaviConfig config ) { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + } + + @Override + public void stopNavi() { + Intent intent = new Intent(); + intent.putExtra( "KEY_TYPE", 10010 ); + sendByIntent( intent ); + } + + @Override + public void startNavi( boolean isRealNavi ) { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + } + + private void sendByIntent( Intent intent ) { + intent.setAction( ACTION_AUTO_MAP ); + intent.addFlags( Intent.FLAG_INCLUDE_STOPPED_PACKAGES ); + mContext.sendBroadcast( intent ); + } + + @Override + public boolean isNaviing() { + return MapState.getInstance().isNaving(); + } + + @Override + public List< MogoCalculatePath > getCalculatedStrategies() { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + return null; + } + + @Override + public List< MogoLatLng > getCalculatedPathPos() { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + return null; + } + + @Override + public OnCalculatePathItemClickInteraction getItemClickInteraction() { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + return null; + } + + @Override + public void setLineClickInteraction( OnCalculatePathItemClickInteraction itemClickInteraction ) { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + } + + @Override + public void clearCalculatePaths() { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + } + + @Override + public void setCalculatePathDisplayBounds( Rect bounds ) { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + } + + @Override + public MogoNaviConfig getNaviConfig() { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + return NaviClient.getInstance( mContext ).getNaviConfig(); + } + + @Override + public boolean setBroadcastMode( int mode ) { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + return false; + } + + @Override + public List< MogoLatLng > getNaviPathCoordinates() { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + return null; + } + + @Override + public MogoLatLng getCarLocation() { + return NaviClient.getInstance( mContext ).getCarLocation(); + } + + @Override + public Location getCarLocation2() { + return NaviClient.getInstance( mContext ).getCarLocation2(); + } + + @Override + public void registerCarLocationChangedListener( IMogoCarLocationChangedListener2 listener ) { + NaviClient.getInstance( mContext ).registerCarLocationChangedListener( listener ); + } + + @Override + public void startAimlessMode() { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + } + + @Override + public void stopAimlessMode() { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + } + + @Override + public void setAimlessModeStatus( boolean open ) { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + } + + @Override + public void displayOverview( Rect bounds ) { + Logger.w( TAG, "高德车机导航,不支持此设置" ); + } + + @Override + public void setUseExtraGPSData( boolean use ) { + NaviClient.getInstance( mContext ).setUseExtraGPSData( use ); + } + + @Override + public void setExtraGPSData( double lon, double lat, float speed, float accuracy, float bearing, long timestamp ) { + NaviClient.getInstance( mContext ).setExtraGPSData( lon, lat, speed, accuracy, bearing, timestamp ); + } +} diff --git a/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/AutoNaviReceiver.java b/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/AutoNaviReceiver.java new file mode 100644 index 0000000000..4d6edfbc86 --- /dev/null +++ b/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/AutoNaviReceiver.java @@ -0,0 +1,147 @@ +package com.mogo.map.impl.automap.navi; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.text.TextUtils; + +import com.mogo.map.impl.amap.utils.IconTypeUtils; +import com.mogo.map.navi.MogoNaviInfo; +import com.mogo.map.navi.MogoNaviListenerHandler; +import com.mogo.map.navi.MogoTraffic; +import com.mogo.utils.logger.Logger; + +/** + * @author congtaowang + * @since 2020/6/2 + *

+ * 高德公版地图透出信息广播接收者 + */ +public class AutoNaviReceiver extends BroadcastReceiver { + + private static final String TAG = "AutoNaviReceiver"; + + public static final String ACTION_AUTONAVI_SEND = "AUTONAVI_STANDARD_BROADCAST_SEND"; + private static AutoNaviReceiver autoNaviReceiver; + private static boolean sRegisterFlag = false; + + + public static void register( Context context ) { + IntentFilter filter = new IntentFilter(); + filter.addAction( ACTION_AUTONAVI_SEND ); + autoNaviReceiver = new AutoNaviReceiver(); + context.registerReceiver( autoNaviReceiver, filter ); + sRegisterFlag = true; + } + + public static void unregister( Context context ) { + if ( autoNaviReceiver != null && sRegisterFlag ) { + try { + context.unregisterReceiver( autoNaviReceiver ); + } catch ( Exception e ) { + Logger.e( TAG, e, "error. " ); + } + } + } + + @Override + public void onReceive( Context context, Intent intent ) { + String action = intent.getAction(); + + if ( !TextUtils.equals( ACTION_AUTONAVI_SEND, action ) ) { + return; + } + + int keyType = intent.getIntExtra( "KEY_TYPE", 0 ); + Logger.d( TAG, "receive: keyType = %d", keyType ); + switch ( keyType ) { + case 10001: + handleAutoNaviInfo( context, intent ); + break; + case 10019: + int state = intent.getIntExtra( "EXTRA_STATE", -1 ); + handleMapStatusChanged( state ); + break; + } + } + + /** + * 在导航/巡航/模拟导航中auto主动将变化的引导信息发送给第三方系统 + * + * @param intent + */ + private void handleAutoNaviInfo( Context context, Intent intent ) { + + int type = intent.getIntExtra( GuideInfoExtraKey.TYPE, -1 ); + + int cameraSpeed = intent.getIntExtra( GuideInfoExtraKey.CAMERA_SPEED, 0 ); + int cameraDisc = intent.getIntExtra( GuideInfoExtraKey.CAMERA_DIST, 0 ); + int cameraType = intent.getIntExtra( GuideInfoExtraKey.CAMERA_TYPE, 0 ); + + if ( type == 0 || type == 1 ) { + if ( !MapState.getInstance().isNaving() + && MogoNaviListenerHandler.getInstance().hasDelegateListener() ) { + MapState.getInstance().setNaving( true ); + MogoNaviListenerHandler.getInstance().onStartNavi(); + } + MogoNaviInfo naviInfo = new MogoNaviInfo(); + naviInfo.setCurrentLimitSpeed( cameraSpeed ); + naviInfo.setCurrentRoadName( intent.getStringExtra( GuideInfoExtraKey.CUR_ROAD_NAME ) ); + naviInfo.setCurrentSpeed( intent.getIntExtra( GuideInfoExtraKey.CUR_SPEED, 0 ) ); + naviInfo.setCurStepRetainDistance( intent.getIntExtra( GuideInfoExtraKey.SEG_REMAIN_DIS, 0 ) ); + naviInfo.setCurStepRetainTime( intent.getIntExtra( GuideInfoExtraKey.SEG_REMAIN_TIME, 0 ) ); + naviInfo.setIconResId( IconTypeUtils.getResIdByIconType( context, intent.getIntExtra( GuideInfoExtraKey.NEW_ICON, 0 ) ) ); + naviInfo.setNextRoadName( intent.getStringExtra( GuideInfoExtraKey.NEXT_ROAD_NAME ) ); + naviInfo.setPathRetainDistance( intent.getIntExtra( GuideInfoExtraKey.ROUTE_REMAIN_DIS, 0 ) ); + naviInfo.setPathRetainTime( intent.getIntExtra( GuideInfoExtraKey.ROUTE_REMAIN_TIME, 0 ) ); + MogoNaviListenerHandler.getInstance().onNaviInfoUpdate( naviInfo ); + } + MogoTraffic mogoTraffic = new MogoTraffic( MapState.getInstance().isAimless() ? MogoTraffic.TYPE_AIM : MogoTraffic.TYPE_NAVI ); + mogoTraffic.setDistance( cameraDisc ); + mogoTraffic.setSpeedLimit( cameraSpeed ); + mogoTraffic.setTrafficType( cameraType ); + MogoNaviListenerHandler.getInstance().onUpdateTraffic2( mogoTraffic ); + } + + /** + * 当导航发生状态变更时,将相应的状态通知给系统。 + * + * @param state + */ + private void handleMapStatusChanged( int state ) { + if ( state == -1 ) { + return; + } + Logger.d( TAG, "map status: state = %d", state ); + switch ( state ) { + case MapStateValue.START_NAVI: + case MapStateValue.START_EMULATOR_NAVI: + if ( MapState.getInstance().isNaving() ) { + return; + } + MapState.getInstance().setNaving( true ); + MogoNaviListenerHandler.getInstance().onStartNavi(); + break; + case MapStateValue.STOP_NAVI: + case MapStateValue.STOP_EMULATOR_NAVI: + case MapStateValue.APP_START: // 语音退出导航,感觉是杀掉了高德APP了 + if ( MapState.getInstance().isNaving() ) { + MapState.getInstance().setNaving( false ); + MogoNaviListenerHandler.getInstance().onStopNavi(); + } + break; + case MapStateValue.START_AIMLESS_NAVI: + MapState.getInstance().setAimless( true ); + break; + case MapStateValue.STOP_AIMLESS_NAVI: + MapState.getInstance().setAimless( false ); + break; + case MapStateValue.EXIT_APP: + break; + case MapStateValue.DESTINATION: + MogoNaviListenerHandler.getInstance().onArriveDestination(); + break; + } + } +} diff --git a/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/GuideInfoExtraKey.java b/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/GuideInfoExtraKey.java new file mode 100644 index 0000000000..f71d166564 --- /dev/null +++ b/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/GuideInfoExtraKey.java @@ -0,0 +1,129 @@ +package com.mogo.map.impl.automap.navi; + +//引导信息对应的KEY值机器描述 +public class GuideInfoExtraKey { + /** + * 导航类型,对应的值为int类型 + * 0:GPS导航 + * 1:模拟导航 + * 2:巡航 + */ + public static final String TYPE = "TYPE"; + + /** + * 当前道路名称,对应的值为String类型 + */ + public static final String CUR_ROAD_NAME = "CUR_ROAD_NAME"; + + /** + * 下一道路名,对应的值为String类型 + */ + public static final String NEXT_ROAD_NAME = "NEXT_ROAD_NAME"; + + /** + * 电子眼限速度,对应的值为int类型,无限速则为0,单位:公里/小时 + */ + public static final String CAMERA_SPEED = "CAMERA_SPEED"; + + /** + * 导航转向图标,对应的值为int类型 + */ + public static final String ICON = "ICON"; + + /** + * 导航最新的转向图标,对应的值为int类型 + */ + public static final String NEW_ICON = "NEW_ICON"; + + /** + * 路径剩余距离,对应的值为int类型,单位:米 + */ + public static final String ROUTE_REMAIN_DIS = "ROUTE_REMAIN_DIS"; + /** + * 路径剩余时间,对应的值为int类型,单位:秒 + */ + public static final String ROUTE_REMAIN_TIME = "ROUTE_REMAIN_TIME"; + + /** + * 当前导航段剩余距离,对应的值为int类型,单位:米 + */ + public static final String SEG_REMAIN_DIS = "SEG_REMAIN_DIS"; + + /** + * 当前导航段剩余时间,对应的值为int类型,单位:秒 + */ + public static final String SEG_REMAIN_TIME = "SEG_REMAIN_TIME"; + + /** + * 路径总距离,对应的值为int类型,单位:米 + */ + public static final String ROUTE_ALL_DIS = "ROUTE_ALL_DIS"; + + /** + * 路径总时间,对应的值为int类型,单位:秒 + */ + public static final String ROUTE_ALL_TIME = "ROUTE_ALL_TIME"; + + /** + * 当前车速,对应的值为int类型,单位:公里/小时 + */ + public static final String CUR_SPEED = "CUR_SPEED"; + + /** + * 当前道路类型,对应的值为int类型 + * 0:高速公路 + * 1:国道 + * 2:省道 + * 3:县道 + * 4:乡公路 + * 5:县乡村内部道路 + * 6:主要大街、城市快速道 * 7:主要道路 + * 8:次要道路 + * 9:普通道路 + * 10:非导航道路 + */ + public static final String ROAD_TYPE = "ROAD_TYPE"; + + /** + * 路径剩余时间,对应的值为String类型,单位:天/小时/分钟 比如:1天2小时, 21小时30分 + * 钟(只用于长安) + */ + public static final String ROUTE_REMAIN_TIME_STRING = "ROUTE_REMAIN_TIME_S TRING"; + + /** + * 下下个路名名称,对应的值为String类型 + */ + public static final String NEXT_NEXT_ROAD_NAME = "NEXT_NEXT_ROAD_NAME"; + /** + * 下下个路口转向图标,对应的值为int类型 + */ + + public static final String NEXT_NEXT_TURN_ICON = "NEXT_NEXT_TURN_ICON"; + + /** + * 距离下下个路口剩余距离,对应的值为int类型,单位:米 + */ + public static final String NEXT_SEG_REMAIN_DIS = "NEXT_SEG_REMAIN_DIS"; + + /** + * 距离下下个路口剩余时间,对应的值为int类型,单位:秒 + */ + public static final String NEXT_SEG_REMAIN_TIME = "NEXT_SEG_REMAIN_TIME"; + + /** + * 距离最近的电子眼距离,对应的值为int类型,单位:米 + */ + public static final String CAMERA_DIST = "CAMERA_DIST"; + + /** + * 电子眼类型,对应的值为int类型 + * 0 测速摄像头 + * 1为监控摄像头 + * 2为闯红灯拍照 + * 3为违章拍照 + * 4为公交专用道摄像头 + * 5为应急车道摄像头 + * 6为非机动车道拍照 + */ + public static final String CAMERA_TYPE = "CAMERA_TYPE"; +} \ No newline at end of file diff --git a/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/MapState.java b/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/MapState.java new file mode 100644 index 0000000000..4b4f2ee126 --- /dev/null +++ b/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/MapState.java @@ -0,0 +1,50 @@ +package com.mogo.map.impl.automap.navi; + +public +/** + * @author congtaowang + * @since 2020/6/3 + * + * 高德地图状态 + */ +class MapState { + + private static volatile MapState sInstance; + + private MapState() { + } + + public static MapState getInstance() { + if ( sInstance == null ) { + synchronized ( MapState.class ) { + if ( sInstance == null ) { + sInstance = new MapState(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + private boolean isNaving = false; + private boolean isAimless = false; + + public boolean isNaving() { + return isNaving; + } + + public void setNaving( boolean naving ) { + isNaving = naving; + } + + public boolean isAimless() { + return isAimless; + } + + public void setAimless( boolean aimless ) { + isAimless = aimless; + } +} diff --git a/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/MapStateValue.java b/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/MapStateValue.java new file mode 100644 index 0000000000..f2913ff1bb --- /dev/null +++ b/libraries/map-autonavi/src/main/java/com/mogo/map/impl/automap/navi/MapStateValue.java @@ -0,0 +1,28 @@ +package com.mogo.map.impl.automap.navi; + +/** + * @author congtaowang + * @since 2020/6/3 + *

+ * 高德公版地图状态值 + */ +public interface MapStateValue { + + int START_NAVI = 8; + + int STOP_NAVI = 9; + + int START_EMULATOR_NAVI = 10; + + int STOP_EMULATOR_NAVI = 12; + + int START_AIMLESS_NAVI = 24; + + int STOP_AIMLESS_NAVI = 25; + + int EXIT_APP = 45; + + int DESTINATION = 39; + + int APP_START = 0; +} diff --git a/libraries/mogo-map-api/.gitignore b/libraries/mogo-map-api/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/libraries/mogo-map-api/.gitignore @@ -0,0 +1 @@ +/build diff --git a/libraries/mogo-map-api/apipackage.txt b/libraries/mogo-map-api/apipackage.txt new file mode 100644 index 0000000000..fb450f44da --- /dev/null +++ b/libraries/mogo-map-api/apipackage.txt @@ -0,0 +1,15 @@ +com.mogo.map.uicontroller +com.mogo.map.search.poisearch +com.mogo.map.search.poisearch.query +com.mogo.map.search.inputtips +com.mogo.map.search.inputtips.query +com.mogo.map.search.geo.query +com.mogo.map.search.geo +com.mogo.map.search +com.mogo.map.navi +com.mogo.map.marker +com.mogo.map.model +com.mogo.map.location +com.mogo.map.listener +com.mogo.map.exception +com.mogo.map \ No newline at end of file diff --git a/libraries/mogo-map-api/build.gradle b/libraries/mogo-map-api/build.gradle new file mode 100644 index 0000000000..cac5399ae1 --- /dev/null +++ b/libraries/mogo-map-api/build.gradle @@ -0,0 +1,43 @@ +apply plugin: 'com.android.library' + +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") + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility 1.8 + targetCompatibility 1.8 + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation rootProject.ext.dependencies.androidxappcompat + if (Boolean.valueOf(RELEASE)) { + implementation rootProject.ext.dependencies.mogoutils + implementation rootProject.ext.dependencies.mogocommons + } else { + implementation project(':foudations:mogo-utils') + implementation project(':foudations:mogo-commons') + } +} + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() diff --git a/libraries/mogo-map-api/consumer-rules.pro b/libraries/mogo-map-api/consumer-rules.pro new file mode 100644 index 0000000000..0bd44f06e8 --- /dev/null +++ b/libraries/mogo-map-api/consumer-rules.pro @@ -0,0 +1,2 @@ +#-----library-MapApi---- +-keep class com.mogo.map.**{*;} \ No newline at end of file diff --git a/libraries/mogo-map-api/gradle.properties b/libraries/mogo-map-api/gradle.properties new file mode 100644 index 0000000000..5d79dcb2d0 --- /dev/null +++ b/libraries/mogo-map-api/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.map +POM_ARTIFACT_ID=mogo-map-api +VERSION_CODE=1 diff --git a/libraries/mogo-map-api/proguard-rules.pro b/libraries/mogo-map-api/proguard-rules.pro new file mode 100644 index 0000000000..9ce36f6363 --- /dev/null +++ b/libraries/mogo-map-api/proguard-rules.pro @@ -0,0 +1,24 @@ +# 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 + +#-----library-MapApi---- +-keep class com.mogo.map.**{*;} \ No newline at end of file diff --git a/libraries/mogo-map-api/src/main/AndroidManifest.xml b/libraries/mogo-map-api/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..6699b2d36f --- /dev/null +++ b/libraries/mogo-map-api/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/IDestroyable.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/IDestroyable.java new file mode 100644 index 0000000000..2e162a2052 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/IDestroyable.java @@ -0,0 +1,12 @@ +package com.mogo.map; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 销毁 + */ +public interface IDestroyable { + + void destroy(); +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/ILifeCycle.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/ILifeCycle.java similarity index 100% rename from libraries/mogo-map/src/main/java/com/mogo/map/ILifeCycle.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/ILifeCycle.java diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/IMogoMap.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/IMogoMap.java similarity index 67% rename from libraries/mogo-map/src/main/java/com/mogo/map/IMogoMap.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/IMogoMap.java index 5ff709f78b..1c648028dd 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/IMogoMap.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/IMogoMap.java @@ -2,6 +2,9 @@ package com.mogo.map; import com.mogo.map.marker.IMogoMarker; import com.mogo.map.marker.MogoMarkerOptions; +import com.mogo.map.overlay.IMogoPolyline; +import com.mogo.map.overlay.MogoPolylineOptions; +import com.mogo.map.uicontroller.IMogoMapUIController; import java.util.ArrayList; @@ -18,24 +21,33 @@ public interface IMogoMap { * * @return */ - IUiSettings getUiSettings(); + IMogoUiSettings getUiSettings(); + + /** + * 操作地图视图 + * + * @return + */ + IMogoMapUIController getUIController(); /** * 在地图上添一个图片标记(marker)对象。 * + * @param tag 标识服务 * @param options * @return */ - IMogoMarker addMarker( MogoMarkerOptions options ); + IMogoMarker addMarker( String tag, MogoMarkerOptions options ); /** * 在地图上添一组图片标记(marker)对象,并设置是否改变地图状态以至于所有的marker对象都在当前地图可视区域范围内显示。 * + * @param tag 标识服务 * @param options * @param moveToCenter * @return */ - ArrayList< IMogoMarker > addMarkers( ArrayList< MogoMarkerOptions > options, boolean moveToCenter ); + ArrayList< IMogoMarker > addMarkers( String tag, ArrayList< MogoMarkerOptions > options, boolean moveToCenter ); /** * 从地图上删除所有的overlay(marker,circle,polyline 等对象)。 @@ -96,4 +108,33 @@ public interface IMogoMap { * 停止当前执行的改变地图状态的动画。 */ void stopAnimation(); + + /** + * 获取比例尺 + * + * @return 当前缩放级别下,地图上1像素点对应的长度,单位米 + */ + float getScalePerPixel(); + + /** + * 改变地图缩放级别 + * + * @param zoom + */ + void changeZoom( float zoom ); + + /** + * 获取缩放比例 + * + * @return + */ + float getZoomLevel(); + + /** + * 添加线段 + * + * @param options + * @return + */ + IMogoPolyline addPolyline( MogoPolylineOptions options ); } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/IMogoMapView.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/IMogoMapView.java similarity index 100% rename from libraries/mogo-map/src/main/java/com/mogo/map/IMogoMapView.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/IMogoMapView.java diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/IUiSettings.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/IMogoUiSettings.java similarity index 98% rename from libraries/mogo-map/src/main/java/com/mogo/map/IUiSettings.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/IMogoUiSettings.java index 85d1895297..a01de2d904 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/IUiSettings.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/IMogoUiSettings.java @@ -6,7 +6,7 @@ package com.mogo.map; *

* 图层控制 */ -public interface IUiSettings { +public interface IMogoUiSettings { /** * 设置比例尺功能是否可用。 diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/MogoBaseMapView.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/MogoBaseMapView.java similarity index 93% rename from libraries/mogo-map/src/main/java/com/mogo/map/MogoBaseMapView.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/MogoBaseMapView.java index 64b4bfee63..ddfd895697 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/MogoBaseMapView.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/MogoBaseMapView.java @@ -4,6 +4,7 @@ import android.content.Context; import android.os.Bundle; import android.util.AttributeSet; import android.view.View; +import android.view.ViewGroup; import android.widget.FrameLayout; import androidx.annotation.Nullable; @@ -41,7 +42,7 @@ public abstract class MogoBaseMapView extends FrameLayout implements ILifeCycle if ( mMapView != null ) { final View mapView = mMapView.getMapView(); if ( mapView != null ) { - addView( mapView ); + addView( mapView, new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) ); MogoMap.getInstance().init( context, getMap() ); } else { Logger.e( TAG, "create MapView instance failed." ); diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/MogoLatLng.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/MogoLatLng.java similarity index 54% rename from libraries/mogo-map/src/main/java/com/mogo/map/MogoLatLng.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/MogoLatLng.java index cfa48c3326..aad7e314fb 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/MogoLatLng.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/MogoLatLng.java @@ -12,11 +12,40 @@ import android.os.Parcelable; public class MogoLatLng implements Parcelable { public final double lat; + @Deprecated public final double lng; + public final double lon; - public MogoLatLng( double lat, double lng ) { + public MogoLatLng( double lat, double lon ) { this.lat = lat; - this.lng = lng; + this.lng = lon; + this.lon = lng; + } + + public double getLat() { + return lat; + } + + /** + * Deprecated, use {@link #getLon()} instead. + * + * @return + */ + @Deprecated + public double getLng() { + return lng; + } + + public double getLon() { + return lon; + } + + @Override + public String toString() { + return "MogoLatLng{" + + "lat=" + lat + + ", lon=" + lon + + '}'; } @Override @@ -28,14 +57,16 @@ public class MogoLatLng implements Parcelable { public void writeToParcel( Parcel dest, int flags ) { dest.writeDouble( this.lat ); dest.writeDouble( this.lng ); + dest.writeDouble( this.lon ); } protected MogoLatLng( Parcel in ) { this.lat = in.readDouble(); this.lng = in.readDouble(); + this.lon = in.readDouble(); } - public static final Parcelable.Creator< MogoLatLng > CREATOR = new Parcelable.Creator< MogoLatLng >() { + public static final Creator< MogoLatLng > CREATOR = new Creator< MogoLatLng >() { @Override public MogoLatLng createFromParcel( Parcel source ) { return new MogoLatLng( source ); diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/MogoMap.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/MogoMap.java similarity index 86% rename from libraries/mogo-map/src/main/java/com/mogo/map/MogoMap.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/MogoMap.java index 7571480782..b2c5986293 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/MogoMap.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/MogoMap.java @@ -2,6 +2,8 @@ package com.mogo.map; import android.content.Context; +import com.mogo.utils.logger.Logger; + /** * @author congtaowang * @since 2019-12-20 @@ -9,6 +11,8 @@ import android.content.Context; * 描述 */ public class MogoMap { + + private static final String TAG = "MogoMap"; private IMogoMap mMap; private Context mContext; @@ -30,6 +34,7 @@ public class MogoMap { } public void init( Context context, IMogoMap map ) { + Logger.d( TAG, "init mogomap" ); this.mContext = context; this.mMap = map; } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/exception/MogoMapException.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/exception/MogoMapException.java similarity index 87% rename from libraries/mogo-map/src/main/java/com/mogo/map/exception/MogoMapException.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/exception/MogoMapException.java index 1c85abbecc..9fd2137025 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/exception/MogoMapException.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/exception/MogoMapException.java @@ -6,7 +6,7 @@ package com.mogo.map.exception; *

* 异常 */ -public class MogoMapException extends Exception { +public class MogoMapException extends RuntimeException { public MogoMapException() { } diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/IMogoHosListenerRegister.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/IMogoHosListenerRegister.java new file mode 100644 index 0000000000..59f78dc16b --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/IMogoHosListenerRegister.java @@ -0,0 +1,15 @@ +package com.mogo.map.listener; + +import com.mogo.map.marker.IMogoMarkerClickListenerRegister; +import com.mogo.map.navi.IMogoNaviListenerRegister; + +/** + * @author congtaowang + * @since 2019-12-29 + *

+ * 主模块需要注册监听的事件 + */ +public interface IMogoHosListenerRegister extends IMogoNaviListenerRegister, + IMogoMapListenerRegister, + IMogoMarkerClickListenerRegister { +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/IMogoMapListener.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/IMogoMapListener.java new file mode 100644 index 0000000000..f5667e96c2 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/IMogoMapListener.java @@ -0,0 +1,65 @@ +package com.mogo.map.listener; + +import android.view.MotionEvent; + +import com.mogo.map.MogoLatLng; +import com.mogo.map.location.MogoLocation; +import com.mogo.map.model.MogoPoi; +import com.mogo.map.uicontroller.EnumMapUI; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * 地图操作回调 + */ +public interface IMogoMapListener { + + /** + * 地图加载完毕 + */ + default void onMapLoaded(){}; + + /** + * 地图点击 + * + * @param motionEvent + */ + default void onTouch( MotionEvent motionEvent ){}; + + /** + * 地图上的任意poi点击 + * + * @param poi + */ + default void onPOIClick( MogoPoi poi ){}; + + /** + * 地图点击 + * + * @param latLng + */ + default void onMapClick( MogoLatLng latLng ){} + + /** + * 地图锁定 + * + * @param isLock + */ + default void onLockMap( boolean isLock ){} + + /** + * 地图白天黑夜、导航视角切换 + * + * @param ui + */ + default void onMapModeChanged( EnumMapUI ui ){} + + /** + * @param latLng 中点的经纬度 + * @param zoom 缩放大小 + * @param tilt 倾斜度 + * @param bearing 旋转角度 + */ + default void onMapChanged( MogoLatLng latLng, float zoom, float tilt, float bearing ){} +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/IMogoMapListenerRegister.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/IMogoMapListenerRegister.java new file mode 100644 index 0000000000..f5c4fbca6b --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/IMogoMapListenerRegister.java @@ -0,0 +1,22 @@ +package com.mogo.map.listener; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * 地图操作回调 + */ +public interface IMogoMapListenerRegister { + + /** + * 注册地图事件 + * + * @param listener 回调事件 + */ + void registerHostMapListener( IMogoMapListener listener ); + + /** + * 反注册注册地图事件 + */ + void unregisterHostMapListener(); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/MogoHosListenerRegister.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/MogoHosListenerRegister.java new file mode 100644 index 0000000000..13fad36120 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/MogoHosListenerRegister.java @@ -0,0 +1,77 @@ +package com.mogo.map.listener; + +import com.mogo.map.marker.IMogoMarkerClickListener; +import com.mogo.map.marker.MogoMarkersHandler; +import com.mogo.map.navi.IMogoAimlessModeListener; +import com.mogo.map.navi.IMogoNaviListener; +import com.mogo.map.navi.MogoNaviListenerHandler; + +/** + * @author congtaowang + * @since 2019-12-29 + *

+ * 描述 + */ +public class MogoHosListenerRegister implements IMogoHosListenerRegister { + + private static volatile MogoHosListenerRegister sInstance; + + private MogoHosListenerRegister() { + } + + public static MogoHosListenerRegister getInstance() { + if ( sInstance == null ) { + synchronized ( MogoHosListenerRegister.class ) { + if ( sInstance == null ) { + sInstance = new MogoHosListenerRegister(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + + @Override + public void registerHostMapListener( IMogoMapListener listener ) { + MogoMapListenerHandler.getInstance().registerHostMapListener( listener ); + } + + @Override + public void unregisterHostMapListener() { + MogoMapListenerHandler.getInstance().unregisterHostMapListener(); + } + + @Override + public void registerHostNaviListener( IMogoNaviListener listener ) { + MogoNaviListenerHandler.getInstance().registerHostNaviListener( listener ); + } + + @Override + public void unregisterHostNaviListener() { + MogoNaviListenerHandler.getInstance().unregisterHostNaviListener(); + } + + @Override + public void registerMarkerClickListener( IMogoMarkerClickListener listener ) { + MogoMarkersHandler.getInstance().registerMarkerClickListener( listener ); + } + + @Override + public void unregisterMarkerClickListener() { + MogoMarkersHandler.getInstance().unregisterMarkerClickListener(); + } + + @Override + public void registerHostAimlessModeListener( IMogoAimlessModeListener listener ) { + MogoNaviListenerHandler.getInstance().registerHostAimlessModeListener( listener ); + } + + @Override + public void unregisterHostAimlessModeListener() { + MogoNaviListenerHandler.getInstance().unregisterHostAimlessModeListener(); + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/MogoMapListenerHandler.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/MogoMapListenerHandler.java new file mode 100644 index 0000000000..186e614ee8 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/listener/MogoMapListenerHandler.java @@ -0,0 +1,102 @@ +package com.mogo.map.listener; + +import android.view.MotionEvent; + +import com.mogo.map.MogoLatLng; +import com.mogo.map.location.MogoLocation; +import com.mogo.map.model.MogoPoi; +import com.mogo.map.navi.MogoNaviInfo; +import com.mogo.map.uicontroller.EnumMapUI; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * 地图监听注册管理 + */ +public class MogoMapListenerHandler implements IMogoMapListener, IMogoMapListenerRegister { + + private static volatile MogoMapListenerHandler sInstance; + + private MogoMapListenerHandler() { + } + + public static MogoMapListenerHandler getInstance() { + if ( sInstance == null ) { + synchronized ( MogoMapListenerHandler.class ) { + if ( sInstance == null ) { + sInstance = new MogoMapListenerHandler(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + /** + * 上层模块代理对象 + */ + private IMogoMapListener mDelegateListener = null; + + @Override + public void registerHostMapListener( IMogoMapListener listener ) { + mDelegateListener = listener; + } + + @Override + public void unregisterHostMapListener() { + mDelegateListener = null; + } + + @Override + public void onMapLoaded() { + if ( mDelegateListener != null ) { + mDelegateListener.onMapLoaded(); + } + } + + @Override + public void onTouch( MotionEvent motionEvent ) { + if ( mDelegateListener != null ) { + mDelegateListener.onTouch( motionEvent ); + } + } + + @Override + public void onPOIClick( MogoPoi poi ) { + if ( mDelegateListener != null ) { + mDelegateListener.onPOIClick( poi ); + } + } + + @Override + public void onMapClick( MogoLatLng latLng ) { + if ( mDelegateListener != null ) { + mDelegateListener.onMapClick( latLng ); + } + } + + @Override + public void onLockMap( boolean isLock ) { + if ( mDelegateListener != null ) { + mDelegateListener.onLockMap( isLock ); + } + } + + @Override + public void onMapModeChanged( EnumMapUI ui ) { + if ( mDelegateListener != null ) { + mDelegateListener.onMapModeChanged( ui ); + } + } + + @Override + public void onMapChanged( MogoLatLng location, float zoom, float tilt, float bearing ) { + if ( mDelegateListener != null ) { + mDelegateListener.onMapChanged( location, zoom, tilt, bearing ); + } + } +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/location/IMogoLocationClient.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/location/IMogoLocationClient.java similarity index 71% rename from libraries/mogo-map/src/main/java/com/mogo/map/location/IMogoLocationClient.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/location/IMogoLocationClient.java index ea24dac392..0c724f645e 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/location/IMogoLocationClient.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/location/IMogoLocationClient.java @@ -30,14 +30,21 @@ public interface IMogoLocationClient { * * @param listener */ - void addLocationListener( ILocationListener listener ); + void addLocationListener( IMogoLocationListener listener ); /** * 注销定位回调 * * @param listener */ - void removeLocationListener( ILocationListener listener ); + void removeLocationListener( IMogoLocationListener listener ); + /** + * 返回上一次有效定位 + * + * @return + */ MogoLocation getLastKnowLocation(); + + void destroy(); } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/location/ILocationListener.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/location/IMogoLocationListener.java similarity index 85% rename from libraries/mogo-map/src/main/java/com/mogo/map/location/ILocationListener.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/location/IMogoLocationListener.java index 7069166e20..adfa1bd924 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/location/ILocationListener.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/location/IMogoLocationListener.java @@ -6,7 +6,7 @@ package com.mogo.map.location; *

* 定位回调 */ -public interface ILocationListener { +public interface IMogoLocationListener { /** * 定位发生改变 diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/location/MogoLocation.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/location/MogoLocation.java similarity index 100% rename from libraries/mogo-map/src/main/java/com/mogo/map/location/MogoLocation.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/location/MogoLocation.java diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoInfoWindowAdapter.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoInfoWindowAdapter.java new file mode 100644 index 0000000000..0d0786991f --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoInfoWindowAdapter.java @@ -0,0 +1,20 @@ +package com.mogo.map.marker; + +import android.view.View; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * 自定义 infowindow 适配器 + */ +public interface IMogoInfoWindowAdapter { + + /** + * 获取infowindow的布局 + * + * @param marker + * @return + */ + View getInfoWindow( IMogoMarker marker ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarker.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarker.java new file mode 100644 index 0000000000..8301124d8b --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarker.java @@ -0,0 +1,321 @@ +package com.mogo.map.marker; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Point; +import android.view.animation.Interpolator; + +import com.mogo.map.MogoLatLng; +import com.mogo.map.marker.anim.OnMarkerAnimationListener; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-18 + *

+ * 地图 marker 抽象 + */ +public interface IMogoMarker { + + /** + * 删除当前marker并销毁Marker的图片等资源 + */ + void destroy(); + + /** + * 删除当前marker。 + */ + void remove(); + + /** + * 隐藏Marker覆盖物的信息窗口。 + */ + void hideInfoWindow(); + + /** + * 设置Marker覆盖物的透明度 + * + * @param alpha + */ + void setAlpha( float alpha ); + + /** + * 设置Marker覆盖物的锚点比例。 + * + * @param anchorU + * @param anchorV + */ + void setAnchor( float anchorU, float anchorV ); + + /** + * 设置Marker覆盖物是否允许拖拽。 + * + * @param paramBoolean + */ + void setDraggable( boolean paramBoolean ); + + /** + * 设置 Marker覆盖物的图标 + * + * @param bitmap + */ + void setIcon( Bitmap bitmap ); + + /** + * 设置 Marker 的图标集合,相同图案的 icon 的 marker 最好使用同一个 BitmapDescriptor 对象以节省内存空间。 + * + * @param icons + */ + void setIcons( ArrayList< Bitmap > icons ); + + /** + * 设置Marker覆盖物的InfoWindow是否允许显示,默认为true + * 设置为false之后, 调用Marker.showInfoWindow() 将不会生效 + * + * @param enabled + */ + void setInfoWindowEnable( boolean enabled ); + + /** + * 设置Marker覆盖物的属性选项类 通过markerOption 给marker设置属性 + * + * @param opt + */ + void setMarkerOptions( MogoMarkerOptions opt ); + + /** + * 可以存储业务相关的数据 + * + * @param object + */ + void setObject( Object object ); + + /** + * @return 用户设置的 object 对象 + */ + Object getObject(); + + /** + * 设置多少帧刷新一次图片资源,Marker动画的间隔时间,值越小动画越快。 + * + * @param period + */ + void setPeriod( int period ); + + /** + * 设置位置 + * + * @param lat + * @param lng + */ + void setPosition( double lat, double lng ); + + /** + * 获取坐标点 + * + * @return + */ + MogoLatLng getPosition(); + + /** + * 设置Marker覆盖物图片旋转的角度,从正北开始,逆时针计算。 + * + * @param rotate + */ + void setRotateAngle( float rotate ); + + /** + * 设置Marker 覆盖物的文字片段。 + * + * @param snippet + */ + void setSnippet( String snippet ); + + /** + * 设置Marker 覆盖物的标题。 + * + * @param title + */ + void setTitle( String title ); + + /** + * 设置当前marker在最上面。 + */ + void setToTop(); + + /** + * 设置 Marker 覆盖物的可见属性。 + * + * @param visible + */ + void setVisible( boolean visible ); + + /** + * 设置Marker覆盖物的z轴值。 + * + * @param zIndex + */ + void setZIndex( int zIndex ); + + /** + * 显示 Marker 覆盖物的信息窗口。 + */ + void showInfoWindow(); + + /** + * 设置点击事件 + * + * @param listener + */ + void setOnMarkerClickListener( IMogoMarkerClickListener listener ); + + /** + * 获取点击事件 + * + * @return + */ + IMogoMarkerClickListener getOnMarkerClickListener(); + + /** + * 设置自定义infowindow代理对象 + * + * @param adapter + */ + void setInfoWindowAdapter( IMogoInfoWindowAdapter adapter ); + + /** + * 自定义 infowindow 样式接口 + * + * @return + */ + IMogoInfoWindowAdapter getInfoWindowAdapter(); + + /** + * 自定义marker样式 + * + * @return + */ + void setMarkerIconView( IMogoMarkerIconViewCreator creator ); + + /** + * 是否被销毁 + * + * @return + */ + boolean isDestroyed(); + + /** + * 设置marker的归属模块 + * + * @param mOwner + */ + void setOwner( String mOwner ); + + /** + * 获取marker的归属模块 + * + * @return + */ + String getOwner(); + + /** + * 设置marker在window的位置 + * + * @param position window 的位置。 + */ + void setPositionByPixels( Point position ); + + /** + * Marker 配置 + * + * @return + */ + MogoMarkerOptions getMogoMarkerOptions(); + + + /** + * 开始缩放动画 + * + * @param duration + * @param interpolator + */ + void startScaleAnimation( float fromX, + float toX, + float fromY, + float toY, + int duration, + Interpolator interpolator ); + + /** + * 缩放动画 + * + * @param fromX + * @param toX + * @param fromY + * @param toY + * @param duration + * @param interpolator + * @param listener + */ + void startScaleAnimation( float fromX, + float toX, + float fromY, + float toY, + int duration, + Interpolator interpolator, + OnMarkerAnimationListener listener ); + + /** + * 缩放动画 + * + * @param fromX + * @param toX + * @param fromY + * @param toY + * @param fromAlpha + * @param toAlpha + * @param duration + * @param interpolator + * @param listener + */ + void startScaleAnimationWithAlpha( float fromX, + float toX, + float fromY, + float toY, + float fromAlpha, + float toAlpha, + int duration, + Interpolator interpolator, + OnMarkerAnimationListener listener ); + + + /** + * 弹跳动画 + * + * @param high + * @param duration + * @param interpolator + * @param listener + */ + void startJumpAnimation( float high, + long duration, + Interpolator interpolator, + OnMarkerAnimationListener listener ); + + /** + * 是否是否可点击 + * + * @param clickable + */ + void setClickable( boolean clickable ); + + /** + * 开始平滑移动 + * + * @param points 坐标点 + * @param duration 时长 + */ + void startSmooth( List< MogoLatLng > points, int duration ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerClickListener.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerClickListener.java new file mode 100644 index 0000000000..966ca196fa --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerClickListener.java @@ -0,0 +1,18 @@ +package com.mogo.map.marker; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * marker 点击事件 + */ +public interface IMogoMarkerClickListener { + + /** + * 事件是否继续往下传递 + * + * @param marker + * @return true - 时间已经处理完毕不继续往下传,否则继续往下传 + */ + boolean onMarkerClicked( IMogoMarker marker ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerClickListenerRegister.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerClickListenerRegister.java new file mode 100644 index 0000000000..9ae5f8aa77 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerClickListenerRegister.java @@ -0,0 +1,23 @@ +package com.mogo.map.marker; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * 地图操作回调 + */ +public interface IMogoMarkerClickListenerRegister { + + /** + * 注册marker回调,各业务模块不用关注 + * + * @param listener + */ + void registerMarkerClickListener( IMogoMarkerClickListener listener ); + + + /** + * 注销marker回调,各业务模块不需要关注 + */ + void unregisterMarkerClickListener(); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerIconViewCreator.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerIconViewCreator.java new file mode 100644 index 0000000000..50089cb15b --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerIconViewCreator.java @@ -0,0 +1,20 @@ +package com.mogo.map.marker; + +import android.view.View; + +/** + * @author congtaowang + * @since 2019-12-29 + *

+ * 动态变换 marker 样式接口 + */ +public interface IMogoMarkerIconViewCreator { + + /** + * 返回自定义marker样式 + * + * @param marker marker 的数据 + * @return + */ + View createView( IMogoMarker marker ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerManager.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerManager.java new file mode 100644 index 0000000000..433b4dada0 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/IMogoMarkerManager.java @@ -0,0 +1,84 @@ +package com.mogo.map.marker; + +import android.content.Context; + +import com.mogo.map.MogoLatLng; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 地图 marker 管理 + */ +public interface IMogoMarkerManager { + + /** + * 添加marker + * + * @param tag 标识调用者 + * @param options + * @return + */ + IMogoMarker addMarker( String tag, MogoMarkerOptions options ); + + /** + * 添加多个marker + * + * @param tag 标识调用者 + * @param options + * @return + */ + List< IMogoMarker > addMarkers( String tag, ArrayList< MogoMarkerOptions > options, boolean moveToCenter ); + + /** + * 移除某一个类型、某个模块的 markers + * + * @param tag + */ + void removeMarkers( String tag ); + + /** + * 移除地图上所有markers + */ + void removeMarkers(); + + /** + * 获取某种类型的全部marker。 + * + * @param tag 业务类型 + * @return + */ + List< IMogoMarker > getMarkers( String tag ); + /** + * 获取所有类型的marker。 + * + * @return + */ + Map< String, List< IMogoMarker > > getAllMarkers( ); + + /** + * 仅保留指定类型的tag + * + * @param tag 需要保留的类型 + */ + void removeMarkersExcept( String tag ); + + /** + * 添加搜索路线 + * + * @param context 上下文 + * @param startPoint 起点 + * @param endPoint 终点 + * @param wayPoints 途经点 + */ + void addRouteWay( Context context, MogoLatLng startPoint, MogoLatLng endPoint, List< MogoLatLng > wayPoints ); + + /** + * 移除添加的导航预测路线 + */ + void removeRouteWayOverlay(); +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/marker/MogoMarkerOptions.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/MogoMarkerOptions.java similarity index 68% rename from libraries/mogo-map/src/main/java/com/mogo/map/marker/MogoMarkerOptions.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/marker/MogoMarkerOptions.java index 7b55d96847..f817138f3c 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/marker/MogoMarkerOptions.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/MogoMarkerOptions.java @@ -1,8 +1,14 @@ package com.mogo.map.marker; import android.graphics.Bitmap; +import android.location.Location; +import android.view.View; + +import com.mogo.map.MogoLatLng; +import com.mogo.map.location.MogoLocation; import java.util.ArrayList; +import java.util.Observable; /** * @author congtaowang @@ -10,7 +16,7 @@ import java.util.ArrayList; *

* 地图marker */ -public class MogoMarkerOptions { +public class MogoMarkerOptions extends Observable { private double latitude; private double longitude; @@ -41,7 +47,7 @@ public class MogoMarkerOptions { // Marker覆盖物锚点在水平范围的比例。 private float u = 0.5f; // Marker覆盖物锚点垂直范围的比例。 - private float v = 0.5f; + private float v = 1f; // 设置Marker覆盖物是否可拖拽。 private boolean draggable = false; @@ -52,7 +58,42 @@ public class MogoMarkerOptions { private int offsetY = 0; // 设置Marker覆盖物 zIndex。 - private float zIndex = 0.0f; + private int zIndex = 0; + // 自定义样式 + private View mIconView; + // marker 归属模块 + private String mOwner; + + private Object mObject; + + /** + * 是否加入marker管理 + */ + private boolean mAutoManager = true; + + public MogoMarkerOptions position( MogoLatLng latLng ){ + if ( latLng != null ) { + latitude( latLng.lat ); + longitude( latLng.lon ); + } + return this; + } + + public MogoMarkerOptions position( MogoLocation location ){ + if ( location != null ) { + latitude( location.getLatitude() ); + longitude( location.getLongitude() ); + } + return this; + } + + public MogoMarkerOptions position( Location location ){ + if ( location != null ) { + latitude( location.getLatitude() ); + longitude( location.getLongitude() ); + } + return this; + } public MogoMarkerOptions latitude( double latitude ) { this.latitude = latitude; @@ -74,6 +115,12 @@ public class MogoMarkerOptions { return this; } + /** + * 优先使用icon作为marker资源 + * + * @param icon + * @return + */ public MogoMarkerOptions icon( Bitmap icon ) { this.icon = icon; return this; @@ -139,11 +186,32 @@ public class MogoMarkerOptions { return this; } - public MogoMarkerOptions zIndex( float zIndex ) { + public MogoMarkerOptions zIndex( int zIndex ) { this.zIndex = zIndex; return this; } + public MogoMarkerOptions object( Object object ) { + this.mObject = object; + return this; + } + + /** + * 自定义marker图层样式,优先使用 icon {@link #icon(Bitmap)}作为marker资源 + * + * @param iconView + * @return + */ + public MogoMarkerOptions icon( View iconView ) { + this.mIconView = iconView; + return this; + } + + public MogoMarkerOptions owner( String owner ) { + this.mOwner = owner; + return this; + } + public double getLatitude() { return latitude; } @@ -216,7 +284,28 @@ public class MogoMarkerOptions { return offsetY; } - public float getzIndex() { + public int getzIndex() { return zIndex; } + + public View getIconView() { + return mIconView; + } + + public String getOwner() { + return mOwner; + } + + public Object getObject() { + return mObject; + } + + public boolean isAutoManager() { + return mAutoManager; + } + + public MogoMarkerOptions autoManager( boolean autoManager ) { + this.mAutoManager = autoManager; + return this; + } } diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/MogoMarkersHandler.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/MogoMarkersHandler.java new file mode 100644 index 0000000000..51425cae06 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/MogoMarkersHandler.java @@ -0,0 +1,141 @@ +package com.mogo.map.marker; + +import android.text.TextUtils; + +import com.mogo.map.listener.IMogoMapListener; +import com.mogo.map.listener.IMogoMapListenerRegister; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * 管理地图上的所有marker + */ +public class MogoMarkersHandler implements IMogoMarkerClickListener, IMogoMarkerClickListenerRegister { + + private static volatile MogoMarkersHandler sInstance; + private IMogoMarkerClickListener mDelegate; + + public static MogoMarkersHandler getInstance() { + if ( sInstance == null ) { + synchronized ( MogoMarkersHandler.class ) { + if ( sInstance == null ) { + sInstance = new MogoMarkersHandler(); + } + } + } + return sInstance; + } + + private Map< String, List< IMogoMarker > > mServicesMarkers = new HashMap<>(); + + private MogoMarkersHandler() { + } + + public synchronized void release() { + sInstance = null; + } + + public synchronized void removeAll() { + final Collection< List< IMogoMarker > > mogoMarkers = mServicesMarkers.values(); + for ( List< IMogoMarker > mogoMarkerList : mogoMarkers ) { + if ( mogoMarkerList != null && !mogoMarkerList.isEmpty() ) { + for ( IMogoMarker mogoMarker : mogoMarkerList ) { + try { + mogoMarker.destroy(); + } catch ( Exception e ) { + e.printStackTrace(); + } + } + } + } + mServicesMarkers.clear(); + } + + public synchronized void remove( String tag ) { + List< IMogoMarker > mogoMarkerList = mServicesMarkers.remove( tag ); + if ( mogoMarkerList != null && !mogoMarkerList.isEmpty() ) { + for ( IMogoMarker mogoMarker : mogoMarkerList ) { + try { + mogoMarker.destroy(); + } catch ( Exception e ) { + e.printStackTrace(); + } + } + mogoMarkerList.clear(); + } + } + + public synchronized List< IMogoMarker > getMarkers( String tag ) { + return mServicesMarkers.get( tag ); + } + + + public synchronized Map< String, List< IMogoMarker > > getAllMarkers() { + return mServicesMarkers; + } + + + public synchronized void add( String tag, IMogoMarker marker ) { + if ( marker == null ) { + return; + } + if ( mServicesMarkers.get( tag ) == null ) { + mServicesMarkers.put( tag, new ArrayList< IMogoMarker >() ); + } + mServicesMarkers.get( tag ).add( marker ); + } + + public synchronized void add( String tag, List< IMogoMarker > markers ) { + if ( markers == null || markers.isEmpty() ) { + return; + } + if ( mServicesMarkers.get( tag ) == null ) { + mServicesMarkers.put( tag, new ArrayList< IMogoMarker >() ); + } + mServicesMarkers.get( tag ).addAll( markers ); + } + + @Override + public void registerMarkerClickListener( IMogoMarkerClickListener listener ) { + mDelegate = listener; + } + + @Override + public void unregisterMarkerClickListener() { + mDelegate = null; + } + + @Override + public boolean onMarkerClicked( IMogoMarker marker ) { + if ( mDelegate != null ) { + return mDelegate.onMarkerClicked( marker ); + } + return false; + } + + /** + * @param tag 需要保留的类型 + */ + public void deleteAllExcept( String tag ) { + if ( TextUtils.isEmpty( tag ) ) { + return; + } + List< IMogoMarker > mogoMarkerList = mServicesMarkers.remove( tag ); + for ( List< IMogoMarker > value : mServicesMarkers.values() ) { + if ( value != null && !value.isEmpty() ) { + for ( IMogoMarker mogoMarker : value ) { + mogoMarker.destroy(); + } + value.clear(); + } + } + mServicesMarkers.put( tag, mogoMarkerList ); + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/anim/OnMarkerAnimationListener.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/anim/OnMarkerAnimationListener.java new file mode 100644 index 0000000000..436e1f0e68 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/marker/anim/OnMarkerAnimationListener.java @@ -0,0 +1,16 @@ +package com.mogo.map.marker.anim; + +/** + * @author congtaowang + * @since 2020-04-22 + *

+ * marker 动画监听 + */ +public interface OnMarkerAnimationListener { + + default void onAnimStart() { + } + + default void onAnimEnd() { + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/model/MogoPoi.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/model/MogoPoi.java new file mode 100644 index 0000000000..c0d287db72 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/model/MogoPoi.java @@ -0,0 +1,76 @@ +package com.mogo.map.model; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.mogo.map.MogoLatLng; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * 地图上的poi + */ +public class MogoPoi implements Parcelable { + + private String name; + private MogoLatLng coordinate; + private String poiId; + + public String getName() { + return name; + } + + public void setName( String name ) { + this.name = name; + } + + public MogoLatLng getCoordinate() { + return coordinate; + } + + public void setCoordinate( MogoLatLng coordinate ) { + this.coordinate = coordinate; + } + + public String getPoiId() { + return poiId; + } + + public void setPoiId( String poiId ) { + this.poiId = poiId; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel( Parcel dest, int flags ) { + dest.writeString( this.name ); + dest.writeParcelable( this.coordinate, flags ); + dest.writeString( this.poiId ); + } + + public MogoPoi() { + } + + protected MogoPoi( Parcel in ) { + this.name = in.readString(); + this.coordinate = in.readParcelable( MogoLatLng.class.getClassLoader() ); + this.poiId = in.readString(); + } + + public static final Parcelable.Creator< MogoPoi > CREATOR = new Parcelable.Creator< MogoPoi >() { + @Override + public MogoPoi createFromParcel( Parcel source ) { + return new MogoPoi( source ); + } + + @Override + public MogoPoi[] newArray( int size ) { + return new MogoPoi[size]; + } + }; +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoAimlessModeListener.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoAimlessModeListener.java new file mode 100644 index 0000000000..4d36b30fb0 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoAimlessModeListener.java @@ -0,0 +1,22 @@ +package com.mogo.map.navi; + +/** + * @author congtaowang + * @since 2020-03-09 + *

+ * 续航模式回调 + */ +public interface IMogoAimlessModeListener { + + /** + * 巡航信息发生改变 + */ + default void onUpdateTraffic2( MogoTraffic traffic ){} + + /** + * 拥堵信息 + * + * @param info + */ + default void onUpdateCongestion( MogoCongestionInfo info ){} +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoCarLocationChangedListener.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoCarLocationChangedListener.java new file mode 100644 index 0000000000..30a1581828 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoCarLocationChangedListener.java @@ -0,0 +1,14 @@ +package com.mogo.map.navi; + +import com.mogo.map.MogoLatLng; + +/** + * @author congtaowang + * @since 2020-03-14 + *

+ * 车辆位置变化 + */ +public interface IMogoCarLocationChangedListener { + + void onCarLocationChanged( MogoLatLng latLng ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoCarLocationChangedListener2.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoCarLocationChangedListener2.java new file mode 100644 index 0000000000..fe2bf33422 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoCarLocationChangedListener2.java @@ -0,0 +1,14 @@ +package com.mogo.map.navi; + +import android.location.Location; + +/** + * @author congtaowang + * @since 2020-03-14 + *

+ * 车辆位置变化 + */ +public interface IMogoCarLocationChangedListener2 extends IMogoCarLocationChangedListener { + + void onCarLocationChanged2( Location latLng ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNavi.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNavi.java new file mode 100644 index 0000000000..de314483b5 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNavi.java @@ -0,0 +1,194 @@ +package com.mogo.map.navi; + +import android.graphics.Rect; +import android.location.Location; + +import com.mogo.map.MogoLatLng; +import com.mogo.map.location.MogoLocation; + +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 导航操作 + */ +public interface IMogoNavi { + + /** + * 开启路径规划并导航 + * + * @param endPoint 目的地 + */ + void naviTo( MogoLatLng endPoint ); + + /** + * 开启路径规划并导航 + * + * @param endPoint 目的地 + * @param config 规划路线策略 + */ + void naviTo( MogoLatLng endPoint, MogoNaviConfig config ); + + /** + * 开启路径规划并导航 + * + * @param endPoint 导航目的地 + * @param wayPoints 途经点 + */ + void naviTo( MogoLatLng endPoint, List< MogoLatLng > wayPoints ); + + /** + * 开启路径规划并导航 + * + * @param endPoint 导航目的地 + * @param wayPoints 途经点 + * @param config 规划路线策略 + */ + void naviTo( MogoLatLng endPoint, List< MogoLatLng > wayPoints, MogoNaviConfig config ); + + /** + * 重新算路 + * + * @param config 规划路线策略 + */ + void reCalculateRoute( MogoNaviConfig config ); + + /** + * 退出导航 + */ + void stopNavi(); + + /** + * 开始导航 + * + * @param isRealNavi true - 实时导航 false - 模拟导航 + */ + void startNavi( boolean isRealNavi ); + + /** + * 是否正在导航 + * + * @return + */ + boolean isNaviing(); + + /** + * 获取路线规划策略 + * + * @return 规划的路线 + */ + List< MogoCalculatePath > getCalculatedStrategies(); + + + /** + * 获取路线坐标点 + * + * @return 规划的路线上所有的坐标点 + */ + List< MogoLatLng > getCalculatedPathPos(); + + + /** + * 获取列表Item点击回调 + * + * @return + */ + OnCalculatePathItemClickInteraction getItemClickInteraction(); + + + /** + * 设置线条点击回调 + */ + void setLineClickInteraction( OnCalculatePathItemClickInteraction itemClickInteraction ); + + /** + * 清除规划的路线 + */ + void clearCalculatePaths(); + + /** + * 设置显示规划路线的范围 + * + * @param bounds 范围 + */ + void setCalculatePathDisplayBounds( Rect bounds ); + + /** + * 导航配置 + * + * @return + */ + MogoNaviConfig getNaviConfig(); + + /** + * 设置播报模式 + * + * @param mode + * @return + */ + boolean setBroadcastMode( int mode ); + + /** + * 获取导航沿途路线的点 + * + * @return + */ + List< MogoLatLng > getNaviPathCoordinates(); + + /** + * 获取车标经纬度 + * + * @return + */ + MogoLatLng getCarLocation(); + + /** + * 获取车标经纬度 + * + * @return + */ + Location getCarLocation2(); + + /** + * 注册车辆位置变化监听,非业务使用 + * + * @param listener + */ + void registerCarLocationChangedListener( IMogoCarLocationChangedListener2 listener ); + + /** + * 打开巡航模式 + */ + void startAimlessMode(); + + /** + * 关闭巡航模式 + */ + void stopAimlessMode(); + + /** + * 设置巡航模式状态 + * + * @param open + */ + void setAimlessModeStatus( boolean open ); + + /** + * 查看全程 + */ + void displayOverview( Rect bounds ); + + /** + * 设置使用外部定位源 + * + * @param use true - 使用,false - 不适用 + */ + void setUseExtraGPSData( boolean use ); + + /** + * 设置外部数据源 + */ + void setExtraGPSData( double lon, double lat, float speed, float accuracy, float bearing, long timestamp ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNaviListener.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNaviListener.java new file mode 100644 index 0000000000..ff989a920f --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNaviListener.java @@ -0,0 +1,54 @@ +package com.mogo.map.navi; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 导航监听 + */ +public interface IMogoNaviListener { + + /** + * 导航初始化失败 + */ + default void onInitNaviFailure(){} + + /** + * 导航初始化成功 + */ + default void onInitNaviSuccess(){} + + /** + * 导航引导信息 + * + * @param naviinfo + */ + default void onNaviInfoUpdate( MogoNaviInfo naviinfo ){} + + /** + * 导航开始回调 + */ + default void onStartNavi(){} + + /** + * 导航停止:包括到达目的地和主动停止导航 + */ + default void onStopNavi(){} + + /** + * 路径规划成功 + */ + default void onCalculateSuccess(){} + + /** + * 路径规划失败 + */ + default void onoCalculateFailed(){} + + /** + * 巡航信息发生改变 + * Deprecated, use {@link IMogoAimlessModeListener#onUpdateTraffic2(MogoTraffic)} instead. + */ + @Deprecated + default void onUpdateTraffic( MogoTraffic traffic ){} +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNaviListener2.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNaviListener2.java new file mode 100644 index 0000000000..c0d261c1d6 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNaviListener2.java @@ -0,0 +1,20 @@ +package com.mogo.map.navi; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 导航监听:区分导航结束 + */ +public interface IMogoNaviListener2 extends IMogoNaviListener { + + /** + * 实际导航结束 + */ + default void onArriveDestination() { } + + /** + * 模拟导航结束 + */ + default void onEndEmulatorNavi(){} +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNaviListenerRegister.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNaviListenerRegister.java new file mode 100644 index 0000000000..b61789d1ad --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/IMogoNaviListenerRegister.java @@ -0,0 +1,34 @@ +package com.mogo.map.navi; + +/** + * @author congtaowang + * @since 2019-12-23 + *

+ * 地图操作回调 + */ +public interface IMogoNaviListenerRegister { + + /** + * 注册导航回调,各业务模块不用关注 + * + * @param listener 回调函数 + */ + void registerHostNaviListener( IMogoNaviListener listener ); + + /** + * 注册巡航模式回调,各业务模块不用关注 + * + * @param listener + */ + void registerHostAimlessModeListener( IMogoAimlessModeListener listener ); + + /** + * 注销导航回调,各业务模块不用关注 + */ + void unregisterHostNaviListener(); + + /** + * 注销巡航回调,各业务模块不用关注 + */ + void unregisterHostAimlessModeListener(); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoCalculatePath.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoCalculatePath.java new file mode 100644 index 0000000000..ec44cd59cb --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoCalculatePath.java @@ -0,0 +1,148 @@ +package com.mogo.map.navi; + +import android.text.TextUtils; +import com.mogo.map.MogoLatLng; +import java.util.List; + +/** + * @author congtaowang + * @since 2020-01-08 + *

+ * 规划路线信息 + */ +public class MogoCalculatePath { + + /** + * 策略名称 + */ + private String mStrategyName; + + /** + * 时间 + */ + private String mFormattedTime; + private int mTime; + + /** + * 距离 + */ + private String mFormattedDistance; + private int mDistance; + + /** + * 红绿灯个数 + */ + private int mTrafficLights; + + /** + * 路线ID,用于选择那一条线 + */ + private String mTagId; + + /** + * 规划的线路ID + */ + private int mPathId; + + + private List coordList; + + public List getCoordList() { + return coordList; + } + + public void setCoordList(List coordList) { + this.coordList = coordList; + } + + public MogoCalculatePath() { + } + + public String getStrategyName() { + if (!TextUtils.isEmpty(mStrategyName)&&mStrategyName.contains(",")) { + String[] split = mStrategyName.split(","); + return split[0]; + } + + return mStrategyName; + } + + public void setStrategyName( String mStrategyName ) { + this.mStrategyName = mStrategyName; + } + + public String getFormattedTime() { + return mFormattedTime; + } + + public void setFormattedTime( String mTime ) { + this.mFormattedTime = mTime; + } + + public String getFormattedDistance() { + return mFormattedDistance; + } + + public void setFormattedDistance( String mDistance ) { + this.mFormattedDistance = mDistance; + } + + public int getTrafficLights() { + return mTrafficLights; + } + + public void setTrafficLights( int mTrafficLights ) { + this.mTrafficLights = mTrafficLights; + } + + + private StringBuilder mDescBuilder = null; + + public String getDesc() { + if ( mDescBuilder == null ) { + mDescBuilder = new StringBuilder(); + int lightsSize = getTrafficLights(); + if ( lightsSize > 0 ) { + mDescBuilder.append( "红绿灯" ).append( lightsSize ).append( "个" ); + } + //mDescBuilder.append( " " ); + //mDescBuilder.append( "收费" ).append( mPath.getTollCost() ).append( "元" ); + } + + return mDescBuilder.toString(); + } + + public String getTagId() { + return mTagId; + } + + public void setTagId( String mTagId ) { + this.mTagId = mTagId; + } + + public int getPathId() { + return mPathId; + } + + public void setPathId( int mPathId ) { + this.mPathId = mPathId; + } + + public int getTime() { + return mTime; + } + + public MogoCalculatePath setTime( int time ) { + this.mTime = time; + return this; + } + + public int getDistance() { + return mDistance; + } + + public MogoCalculatePath setDistance( int distance ) { + this.mDistance = distance; + return this; + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoCongestionInfo.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoCongestionInfo.java new file mode 100644 index 0000000000..b064864c39 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoCongestionInfo.java @@ -0,0 +1,133 @@ +package com.mogo.map.navi; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.List; + +/** + * @author congtaowang + * @since 2020-03-09 + *

+ * 拥堵详情 + */ +public class MogoCongestionInfo implements Parcelable { + + private int mTime; + private int mLength; + private String mRoadName; + private int mCongestionStatus; + private int mEventType; + private double mEventLon; + private double mEventLat; + + private List< MogoCongestionLink > mCongestionLinks; + + + public MogoCongestionInfo() { + } + + public int getTime() { + return mTime; + } + + public void setTime( int mTime ) { + this.mTime = mTime; + } + + public int getLength() { + return mLength; + } + + public void setLength( int mLength ) { + this.mLength = mLength; + } + + public String getRoadName() { + return mRoadName; + } + + public void setRoadName( String mRoadName ) { + this.mRoadName = mRoadName; + } + + public int getCongestionStatus() { + return mCongestionStatus; + } + + public void setCongestionStatus( int mCongestionStatus ) { + this.mCongestionStatus = mCongestionStatus; + } + + public int getEventType() { + return mEventType; + } + + public void setEventType( int mEventType ) { + this.mEventType = mEventType; + } + + public double getEventLon() { + return mEventLon; + } + + public void setEventLon( double mEventLon ) { + this.mEventLon = mEventLon; + } + + public double getEventLat() { + return mEventLat; + } + + public void setEventLat( double mEventLat ) { + this.mEventLat = mEventLat; + } + + public List< MogoCongestionLink > getCongestionLinks() { + return mCongestionLinks; + } + + public void setCongestionLinks( List< MogoCongestionLink > mCongestionLinks ) { + this.mCongestionLinks = mCongestionLinks; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel( Parcel dest, int flags ) { + dest.writeInt( this.mTime ); + dest.writeInt( this.mLength ); + dest.writeString( this.mRoadName ); + dest.writeInt( this.mCongestionStatus ); + dest.writeInt( this.mEventType ); + dest.writeDouble( this.mEventLon ); + dest.writeDouble( this.mEventLat ); + dest.writeTypedList( this.mCongestionLinks ); + } + + protected MogoCongestionInfo( Parcel in ) { + this.mTime = in.readInt(); + this.mLength = in.readInt(); + this.mRoadName = in.readString(); + this.mCongestionStatus = in.readInt(); + this.mEventType = in.readInt(); + this.mEventLon = in.readDouble(); + this.mEventLat = in.readDouble(); + this.mCongestionLinks = in.createTypedArrayList( MogoCongestionLink.CREATOR ); + } + + public static final Creator< MogoCongestionInfo > CREATOR = new Creator< MogoCongestionInfo >() { + @Override + public MogoCongestionInfo createFromParcel( Parcel source ) { + return new MogoCongestionInfo( source ); + } + + @Override + public MogoCongestionInfo[] newArray( int size ) { + return new MogoCongestionInfo[size]; + } + }; +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoCongestionLink.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoCongestionLink.java new file mode 100644 index 0000000000..47ac00720a --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoCongestionLink.java @@ -0,0 +1,69 @@ +package com.mogo.map.navi; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.mogo.map.MogoLatLng; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author congtaowang + * @since 2020-03-09 + *

+ * 描述 + */ +public class MogoCongestionLink implements Parcelable { + + private ArrayList< MogoLatLng > mCoords; + private int mCongestionStatus; + + + public MogoCongestionLink() { + } + + public List< MogoLatLng > getCoords() { + return mCoords; + } + + public void setCoords( ArrayList< MogoLatLng > mCoords ) { + this.mCoords = mCoords; + } + + public int getCongestionStatus() { + return mCongestionStatus; + } + + public void setCongestionStatus( int mCongestionStatus ) { + this.mCongestionStatus = mCongestionStatus; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel( Parcel dest, int flags ) { + dest.writeTypedList( this.mCoords ); + dest.writeInt( this.mCongestionStatus ); + } + + protected MogoCongestionLink( Parcel in ) { + this.mCoords = in.createTypedArrayList( MogoLatLng.CREATOR ); + this.mCongestionStatus = in.readInt(); + } + + public static final Creator< MogoCongestionLink > CREATOR = new Creator< MogoCongestionLink >() { + @Override + public MogoCongestionLink createFromParcel( Parcel source ) { + return new MogoCongestionLink( source ); + } + + @Override + public MogoCongestionLink[] newArray( int size ) { + return new MogoCongestionLink[size]; + } + }; +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoNaviConfig.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoNaviConfig.java new file mode 100644 index 0000000000..a27c120c24 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoNaviConfig.java @@ -0,0 +1,105 @@ +package com.mogo.map.navi; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 导航参数 + */ +public class MogoNaviConfig { + + /** + * 是否躲避拥堵 + */ + private boolean congestion = false; + + /** + * 不走高速 + */ + private boolean avoidSpeed = false; + + /** + * 避免收费 + */ + private boolean cost = false; + + /** + * 高速优先 + */ + private boolean highSpeed = false; + + /** + * 是否多路线算路 + */ + private boolean multipleRoute = true; + + /** + * 是否躲避拥堵 + */ + public MogoNaviConfig congestion( boolean congestion ) { + this.congestion = congestion; + return this; + } + + /** + * 不走高速 + */ + public MogoNaviConfig avoidSpeed( boolean avoidSpeed ) { + this.avoidSpeed = avoidSpeed; + if (avoidSpeed) { + this.highSpeed = false; + } + return this; + } + + /** + * 避免收费 + */ + public MogoNaviConfig cost( boolean cost ) { + this.cost = cost; + if (cost) { + this.highSpeed = false; + } + return this; + } + + /** + * 高速优先 + */ + public MogoNaviConfig highSpeed( boolean highSpeed ) { + this.highSpeed = highSpeed; + if (highSpeed) { + this.avoidSpeed = false; + this.cost = false; + } + return this; + } + + /** + * 是否多路线算路 + */ + public MogoNaviConfig multipleRoute( boolean multipleRoute ) { + this.multipleRoute = multipleRoute; + return this; + } + + public boolean isCongestion() { + return congestion; + } + + public boolean isAvoidSpeed() { + return avoidSpeed; + } + + public boolean isCost() { + return cost; + } + + public boolean isHighSpeed() { + return highSpeed; + } + + public boolean isMultipleRoute() { + return multipleRoute; + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoNaviInfo.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoNaviInfo.java new file mode 100644 index 0000000000..633af674bc --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoNaviInfo.java @@ -0,0 +1,210 @@ +package com.mogo.map.navi; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.DrawableRes; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 导航引导信息 + */ +public class MogoNaviInfo implements Parcelable { + + /** + * 当前路线名称 + */ + private String currentRoadName; + + /** + * 导航过程中当前的车速 + */ + private int currentSpeed; + + /** + * 当前路段剩余距离 + */ + private int curStepRetainDistance; + + /** + * 当前路段剩余时间 + */ + private int curStepRetainTime; + + /** + * 导航转向图标资源ID + */ + @DrawableRes + private int iconResId; + + /** + * 下条路名 + */ + private String nextRoadName; + + /** + * 剩余时间(秒) + */ + private int pathRetainTime; + + /** + * 剩余距离 + */ + private int pathRetainDistance; + + /** + * 当前限速 + */ + private float currentLimitSpeed; + + public String getCurrentRoadName() { + return currentRoadName; + } + + public void setCurrentRoadName(String currentRoadName) { + this.currentRoadName = currentRoadName; + } + + public int getCurrentSpeed() { + return currentSpeed; + } + + public void setCurrentSpeed(int currentSpeed) { + this.currentSpeed = currentSpeed; + } + + public int getCurStepRetainDistance() { + return curStepRetainDistance; + } + + public void setCurStepRetainDistance(int curStepRetainDistance) { + this.curStepRetainDistance = curStepRetainDistance; + } + + public int getCurStepRetainTime() { + return curStepRetainTime; + } + + public void setCurStepRetainTime(int curStepRetainTime) { + this.curStepRetainTime = curStepRetainTime; + } + + public int getIconResId() { + return iconResId; + } + + public void setIconResId(int iconResId) { + this.iconResId = iconResId; + } + + public String getNextRoadName() { + return nextRoadName; + } + + public void setNextRoadName(String nextRoadName) { + this.nextRoadName = nextRoadName; + } + + public int getPathRetainTime() { + return pathRetainTime; + } + + public void setPathRetainTime(int pathRetainTime) { + this.pathRetainTime = pathRetainTime; + } + + public int getPathRetainDistance() { + return pathRetainDistance; + } + + public String getVoiceRetainDistance() { + + StringBuilder builder = new StringBuilder(); + if (pathRetainDistance >= 1000) { + builder.append(String.format("%.1f公里", pathRetainDistance / 1000f)); + } else { + builder.append(pathRetainDistance).append("米"); + } + + return builder.toString(); + } + + public String getVoiceRetainTime() { + StringBuilder builder = new StringBuilder(); + int seconds = pathRetainTime; + int days = seconds / (24 * 60 * 60); + if (days > 0) { + builder.append(days).append("天"); + } + seconds -= days * 24 * 60 * 60; + int hours = seconds / (60 * 60); + if (hours > 0) { + builder.append(hours).append("小时"); + } + seconds -= hours * 60 * 60; + int min = seconds / 60; + builder.append(min > 1 ? min : 1).append("分钟"); + return builder.toString(); + + } + + public void setPathRetainDistance(int pathRetainDistance) { + this.pathRetainDistance = pathRetainDistance; + } + + public float getCurrentLimitSpeed() { + return currentLimitSpeed; + } + + public void setCurrentLimitSpeed(float currentLimitSpeed) { + this.currentLimitSpeed = currentLimitSpeed; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(this.currentRoadName); + dest.writeInt(this.currentSpeed); + dest.writeInt(this.curStepRetainDistance); + dest.writeInt(this.curStepRetainTime); + dest.writeInt(this.iconResId); + dest.writeString(this.nextRoadName); + dest.writeInt(this.pathRetainTime); + dest.writeInt(this.pathRetainDistance); + dest.writeFloat(this.currentLimitSpeed); + } + + public MogoNaviInfo() { + } + + protected MogoNaviInfo(Parcel in) { + this.currentRoadName = in.readString(); + this.currentSpeed = in.readInt(); + this.curStepRetainDistance = in.readInt(); + this.curStepRetainTime = in.readInt(); + this.iconResId = in.readInt(); + this.nextRoadName = in.readString(); + this.pathRetainTime = in.readInt(); + this.pathRetainDistance = in.readInt(); + this.currentLimitSpeed = in.readFloat(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public MogoNaviInfo createFromParcel(Parcel source) { + return new MogoNaviInfo(source); + } + + @Override + public MogoNaviInfo[] newArray(int size) { + return new MogoNaviInfo[size]; + } + }; +} + diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoNaviListenerHandler.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoNaviListenerHandler.java new file mode 100644 index 0000000000..a4f7ec758c --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoNaviListenerHandler.java @@ -0,0 +1,152 @@ +package com.mogo.map.navi; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * 地图监听注册管理 + */ +public class MogoNaviListenerHandler implements IMogoNaviListener2, IMogoNaviListenerRegister, IMogoAimlessModeListener { + + private static volatile MogoNaviListenerHandler sInstance; + + private MogoNaviListenerHandler() { + } + + public static MogoNaviListenerHandler getInstance() { + if ( sInstance == null ) { + synchronized ( MogoNaviListenerHandler.class ) { + if ( sInstance == null ) { + sInstance = new MogoNaviListenerHandler(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + /** + * 上层模块代理对象 + */ + private IMogoNaviListener mDelegateListener = null; + + /** + * @return + */ + public boolean hasDelegateListener(){ + return mDelegateListener != null; + } + + /** + * 上层模块代理对象 + */ + private IMogoAimlessModeListener mAimlessDelegateListener = null; + + @Override + public void registerHostNaviListener( IMogoNaviListener listener ) { + mDelegateListener = listener; + } + + @Override + public void unregisterHostNaviListener() { + mDelegateListener = null; + } + + @Override + public void registerHostAimlessModeListener( IMogoAimlessModeListener listener ) { + mAimlessDelegateListener = listener; + } + + @Override + public void unregisterHostAimlessModeListener() { + mAimlessDelegateListener = null; + } + + @Override + public synchronized void onInitNaviFailure() { + if ( mDelegateListener != null ) { + mDelegateListener.onInitNaviFailure(); + } + } + + @Override + public synchronized void onInitNaviSuccess() { + if ( mDelegateListener != null ) { + mDelegateListener.onInitNaviSuccess(); + } + } + + @Override + public synchronized void onNaviInfoUpdate( MogoNaviInfo naviinfo ) { + if ( mDelegateListener != null ) { + mDelegateListener.onNaviInfoUpdate( naviinfo ); + } + } + + @Override + public synchronized void onStartNavi() { + if ( mDelegateListener != null ) { + mDelegateListener.onStartNavi(); + } + } + + @Override + public synchronized void onStopNavi() { + if ( mDelegateListener != null ) { + mDelegateListener.onStopNavi(); + } + } + + @Override + public void onCalculateSuccess() { + if ( mDelegateListener != null ) { + mDelegateListener.onCalculateSuccess(); + } + } + + @Override + public void onoCalculateFailed() { + if ( mDelegateListener != null ) { + mDelegateListener.onoCalculateFailed(); + } + } + + @Override + @Deprecated + public void onUpdateTraffic( MogoTraffic traffic ) { + if ( mDelegateListener != null ) { + mDelegateListener.onUpdateTraffic( traffic ); + } + } + + @Override + public void onUpdateTraffic2( MogoTraffic traffic ) { + if ( mAimlessDelegateListener != null ) { + mAimlessDelegateListener.onUpdateTraffic2( traffic ); + } + } + + @Override + public void onUpdateCongestion( MogoCongestionInfo info ) { + if ( mAimlessDelegateListener != null ) { + mAimlessDelegateListener.onUpdateCongestion( info ); + } + } + + @Override + public void onArriveDestination() { + if ( mDelegateListener instanceof IMogoNaviListener2 ) { + ( ( IMogoNaviListener2 ) mDelegateListener ).onArriveDestination(); + } + } + + @Override + public void onEndEmulatorNavi() { + if ( mDelegateListener instanceof IMogoNaviListener2 ) { + ( ( IMogoNaviListener2 ) mDelegateListener ).onEndEmulatorNavi(); + } + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoTraffic.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoTraffic.java new file mode 100644 index 0000000000..bfa29696ec --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/MogoTraffic.java @@ -0,0 +1,246 @@ +package com.mogo.map.navi; + +/** + * @author congtaowang + * @since 2020-01-16 + *

+ * 巡航信息、导航信息 + */ +public class MogoTraffic { + + /** + * 导航 + */ + public static final int TYPE_NAVI = 1; + + /** + * 巡航 + */ + public static final int TYPE_AIM = 2; + + /** + * 导航 or 巡航 + */ + private int mFromType; + + /** + * 距离 + */ + private int mDistance; + + /** + * 限速 + */ + private int mSpeedLimit; + + /** + * 经度 + */ + private double mLon; + + /** + * 维度 + */ + private double mLat; + + /** + * 交通类型 + * 0 未知道路设施 + * 4 测速摄像头、测速雷达 + * 5 违章摄像头 + * 10 请谨慎驾驶 + * 11 有连续拍照 + * 12 铁路道口 + * 13 注意落石(左侧) + * 14 事故易发地段 + * 15 易滑 + * 16 村庄 + * 18 前方学校 + * 19 有人看管的铁路道口 + * 20 无人看管的铁路道口 + * 21 两侧变窄 + * 22 向左急弯路 + * 23 向右急弯路 + * 24 反向弯路 + * 25 连续弯路 + * 26 左侧合流标识牌 + * 27 右侧合流标识牌 + * 28 监控摄像头 + * 29 专用道摄像头 + * 31 禁止超车 + * 36 右侧变窄 + * 37 左侧变窄 + * 38 窄桥 + * 39 左右绕行 + * 40 左侧绕行 + * 41 右侧绕行 + * 42 注意落石(右侧) + * 43 傍山险路(左侧) + * 44 傍山险路(右侧) + * 47 上陡坡 + * 48 下陡坡 + * 49 过水路面 + * 50 路面不平 + * 52 慢行 + * 53 注意危险 + * 58 隧道 + * 59 渡口 + * 92 闯红灯 + * 93 应急车道 + * 94 非机动车道 + * 100 不绑定电子眼高发地 + * 101 车道违章 + * 102 超速违章 + */ + private int mTrafficType; + + public MogoTraffic( int fromType ) { + mFromType = fromType; + } + + public int getFromType() { + return mFromType; + } + + public void setFromType( int fromType ) { + this.mFromType = fromType; + } + + public int getDistance() { + return mDistance; + } + + public void setDistance( int distance ) { + this.mDistance = distance; + } + + public int getSpeedLimit() { + return mSpeedLimit < 0 ? 0 : mSpeedLimit; + } + + public void setSpeedLimit( int speedLimit ) { + this.mSpeedLimit = speedLimit; + } + + public String getDesc() { + switch ( getTrafficType() ) { + case 0: + default: + return "未知道路设施"; + case 4: + return "测速摄像头、测速雷达"; + case 5: + return "违章摄像头"; + case 10: + return "请谨慎驾驶"; + case 11: + return "有连续拍照"; + case 12: + return "铁路道口"; + case 13: + return "注意落石(左侧)"; + case 14: + return "事故易发地段"; + case 15: + return "易滑"; + case 16: + return "村庄"; + case 18: + return "前方学校"; + case 19: + return "有人看管的铁路道口"; + case 20: + return "无人看管的铁路道口"; + case 21: + return "两侧变窄"; + case 22: + return "向左急弯路"; + case 23: + return "向右急弯路"; + case 24: + return "反向弯路"; + case 25: + return "连续弯路"; + case 26: + return "左侧合流标识牌"; + case 27: + return "右侧合流标识牌"; + case 28: + return "监控摄像头"; + case 29: + return "专用道摄像头"; + case 31: + return "禁止超车"; + case 36: + return "右侧变窄"; + case 37: + return "左侧变窄"; + case 38: + return "窄桥"; + case 39: + return "左右绕行"; + case 40: + return "左侧绕行"; + case 41: + return "右侧绕行"; + case 42: + return "注意落石(右侧)"; + case 43: + return "傍山险路(左侧)"; + case 44: + return "傍山险路(右侧)"; + case 47: + return "上陡坡"; + case 48: + return "下陡坡"; + case 49: + return "过水路面"; + case 50: + return "路面不平"; + case 52: + return "慢行"; + case 53: + return "注意危险"; + case 58: + return "隧道"; + case 59: + return "渡口"; + case 92: + return "闯红灯"; + case 93: + return "应急车道"; + case 94: + return "非机动车道"; + case 100: + return "不绑定电子眼高发地"; + case 101: + return "车道违章"; + case 102: + return "超速违章"; + } + } + + public double getLon() { + return mLon; + } + + public void setLon( double lon ) { + this.mLon = lon; + } + + public double getLat() { + return mLat; + } + + public void setLat( double lat ) { + this.mLat = lat; + } + + public int getTrafficType() { + return mTrafficType; + } + + public void setTrafficType( int trafficType ) { + this.mTrafficType = trafficType; + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/OnCalculatePathItemClickInteraction.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/OnCalculatePathItemClickInteraction.java new file mode 100644 index 0000000000..44ba15b4a0 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/navi/OnCalculatePathItemClickInteraction.java @@ -0,0 +1,14 @@ +package com.mogo.map.navi; + +/** + * 规划路线交互接口 + */ +public interface OnCalculatePathItemClickInteraction { + + /** + * 点击:列表点击、线路点击 + * + * @param tagId 线条ID + */ + void onItemClicked( String tagId ); +} \ No newline at end of file diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/overlay/IMogoOverlayManager.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/overlay/IMogoOverlayManager.java new file mode 100644 index 0000000000..f429797e1a --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/overlay/IMogoOverlayManager.java @@ -0,0 +1,18 @@ +package com.mogo.map.overlay; + +/** + * @author congtaowang + * @since 2020-03-10 + *

+ * 覆盖物 + */ +public interface IMogoOverlayManager { + + /** + * 绘制线段 + * + * @param options + * @return + */ + IMogoPolyline addPolyline( MogoPolylineOptions options ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/overlay/IMogoPolyline.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/overlay/IMogoPolyline.java new file mode 100644 index 0000000000..f20e545720 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/overlay/IMogoPolyline.java @@ -0,0 +1,144 @@ +package com.mogo.map.overlay; + +import androidx.annotation.ColorInt; + +import com.mogo.map.IDestroyable; +import com.mogo.map.MogoLatLng; + +import java.util.List; + +/** + * @author congtaowang + * @since 2020-03-10 + *

+ * 线段 + */ +public interface IMogoPolyline extends IDestroyable { + + + /** + * 是否已经销毁 + * + * @return + */ + boolean isDestroyed(); + + /** + * 移除 + */ + void remove(); + + /** + * 获取ID + * + * @return + */ + String getId(); + + /** + * 设置绘制点数据 + * + * @param lonLats + */ + void setPoints( List< MogoLatLng > lonLats ); + + /** + * 获取点 + * + * @return + */ + List< MogoLatLng > getPoints(); + + /** + * 测地线 + * + * @param draw + */ + void setGeodesic( boolean draw ); + + /** + * 是否设置了测地线 + * + * @return + */ + boolean isGeodesic(); + + /** + * 虚线 + * + * @param dottedLine + */ + void setDottedLine( boolean dottedLine ); + + /** + * 是否是虚线 + * + * @return + */ + boolean isDottedLine(); + + /** + * 设置线宽 + * + * @param width + */ + void setWidth( float width ); + + /** + * 获取线宽 + * + * @return + */ + float getWidth(); + + /** + * 设置线条颜色 + * + * @param color + */ + void setColor( @ColorInt int color ); + + /** + * 获取线条颜色 + * + * @return + */ + @ColorInt + int getColor(); + + /** + * 设置Z轴 + */ + void setZIndex( float zIndex ); + + /** + * 获取Z轴 + * + * @return + */ + float getZIndex(); + + /** + * 设置显示/隐藏 + */ + void setVisible( boolean visible ); + + /** + * 是否可见 + * + * @return + */ + boolean isVisible(); + + /** + * 设置透明度 + * + * @param transparency + */ + void setTransparency( float transparency ); + + /** + * 设置配置项 + */ + void setOption( MogoPolylineOptions option ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/overlay/MogoPolylineOptions.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/overlay/MogoPolylineOptions.java new file mode 100644 index 0000000000..9ac5f29631 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/overlay/MogoPolylineOptions.java @@ -0,0 +1,228 @@ +package com.mogo.map.overlay; + +import android.graphics.Color; + +import androidx.annotation.ColorInt; + +import com.mogo.map.MogoLatLng; +import com.mogo.map.location.MogoLocation; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author congtaowang + * @since 2020-03-10 + *

+ * 线段属性 + */ +public class MogoPolylineOptions { + + private List< MogoLatLng > mPoints; + private float mWidth = 10.0F; + private int mColor = Color.BLACK; + private float mZIndex = 0.0F; + private boolean mIsVisible = true; + private boolean mIsGeodesic = false; + private boolean mIsDottedLine = false; + private boolean mIsGradient = false; + private float mTransparency = 1.0F; + private boolean mIsAboveMaskLayer = false; + private boolean mIsPointsUpdated = false; + private List< Integer > mColorValues; + + public MogoPolylineOptions() { + this.mPoints = new ArrayList<>(); + } + + /** + * 设置顶点 + * + * @param points + * @return + */ + public MogoPolylineOptions points( List< MogoLatLng > points ) { + this.mPoints.clear(); + this.mPoints.addAll( points ); + this.mIsPointsUpdated = true; + return this; + } + + /** + * 添加顶点到集合最后 + * + * @param points + * @return + */ + public MogoPolylineOptions add( MogoLatLng... points ) { + if ( points != null ) { + this.mPoints.addAll( Arrays.asList( points ) ); + this.mIsPointsUpdated = true; + } + return this; + } + + public MogoPolylineOptions add( double lon, double lat ) { + this.mPoints.add( new MogoLatLng( lat, lon ) ); + return this; + } + + public MogoPolylineOptions add( MogoLocation location ) { + if ( location != null ) { + this.mPoints.add( new MogoLatLng( location.getLatitude(), location.getLongitude() ) ); + } + return this; + } + + /** + * 设置线宽 + */ + public MogoPolylineOptions width( float width ) { + this.mWidth = width; + return this; + } + + /** + * 设置线的颜色 + * + * @param color + * @return + */ + public MogoPolylineOptions color( @ColorInt int color ) { + this.mColor = color; + return this; + } + + /** + * 设置Z轴的值 + * + * @param zIndex + * @return + */ + public MogoPolylineOptions zIndex( float zIndex ) { + this.mZIndex = zIndex; + return this; + } + + /** + * 设置是否可见 + * + * @param isVisible + * @return + */ + public MogoPolylineOptions visible( boolean isVisible ) { + this.mIsVisible = isVisible; + return this; + } + + /** + * 设置是否绘制测地线 + * + * @param isGeodesic + * @return + */ + public MogoPolylineOptions geodesic( boolean isGeodesic ) { + this.mIsGeodesic = isGeodesic; + return this; + } + + /** + * 是否是虚线 + * + * @param isDottedLine + * @return + */ + public MogoPolylineOptions dottedLine( boolean isDottedLine ) { + this.mIsDottedLine = isDottedLine; + return this; + } + + /** + * 是否使用渐变色 + * + * @param isGradient + * @return + */ + public MogoPolylineOptions useGradient( boolean isGradient ) { + this.mIsGradient = isGradient; + return this; + } + + /** + * 设置透明度 + * + * @param transparency + * @return + */ + public MogoPolylineOptions transparency( float transparency ) { + this.mTransparency = transparency; + return this; + } + + /** + * @param isAboveMaskLayer + * @return + */ + public MogoPolylineOptions aboveMaskLayer( boolean isAboveMaskLayer ) { + this.mIsAboveMaskLayer = isAboveMaskLayer; + return this; + } + + /** + * @param colors + * @return + */ + public MogoPolylineOptions colorValues( List< Integer > colors ) { + mColorValues = colors; + return this; + } + + public List< MogoLatLng > getPoints() { + return mPoints; + } + + public float getWidth() { + return mWidth; + } + + public int getColor() { + return mColor; + } + + public float getZIndex() { + return mZIndex; + } + + public boolean isVisible() { + return mIsVisible; + } + + public boolean isGeodesic() { + return mIsGeodesic; + } + + public boolean isDottedLine() { + return mIsDottedLine; + } + + public boolean isGradient() { + return mIsGradient; + } + + public float getTransparency() { + return mTransparency; + } + + public boolean isAboveMaskLayer() { + return mIsAboveMaskLayer; + } + + public boolean isPointsUpdated() { + return mIsPointsUpdated; + } + + public List< Integer > getColorValues() { + return mColorValues; + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/search/drive/IMogoRoadSearch.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/drive/IMogoRoadSearch.java new file mode 100644 index 0000000000..934380bb86 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/drive/IMogoRoadSearch.java @@ -0,0 +1,16 @@ +package com.mogo.map.search.drive; + +import android.content.Context; + +/** + * @author congtaowang + * @since 2020/6/1 + *

+ * 驾驶路线 + */ +public interface IMogoRoadSearch { + + void searchRoadPath( Context context, MogoRoadSearchQuery query ); + + void setRoadPathSearchListener( IMogoRoadSearchListener listener ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/search/drive/IMogoRoadSearchListener.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/drive/IMogoRoadSearchListener.java new file mode 100644 index 0000000000..87d3c5eb3d --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/drive/IMogoRoadSearchListener.java @@ -0,0 +1,16 @@ +package com.mogo.map.search.drive; + +import com.mogo.map.MogoLatLng; + +import java.util.List; + +/** + * @author congtaowang + * @since 2020/6/1 + *

+ * 描述 + */ +public interface IMogoRoadSearchListener { + + void onDrivePathSearched( List< MogoLatLng > points ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/search/drive/MogoRoadSearchQuery.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/drive/MogoRoadSearchQuery.java new file mode 100644 index 0000000000..00684eb74c --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/drive/MogoRoadSearchQuery.java @@ -0,0 +1,36 @@ +package com.mogo.map.search.drive; + +import com.mogo.map.MogoLatLng; + +import java.util.List; + +/** + * @author congtaowang + * @since 2020/6/1 + *

+ * 描述 + */ +public class MogoRoadSearchQuery { + + public MogoLatLng mStart; + public MogoLatLng mTarget; + public List mWays; + + public MogoRoadSearchQuery() { + } + + public MogoRoadSearchQuery setStart( MogoLatLng start ) { + this.mStart = start; + return this; + } + + public MogoRoadSearchQuery setTarget( MogoLatLng target ) { + this.mTarget = target; + return this; + } + + public MogoRoadSearchQuery setWays( List< MogoLatLng > ways ) { + this.mWays = ways; + return this; + } +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoGeoSearch.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/IMogoGeoSearch.java similarity index 79% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoGeoSearch.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/IMogoGeoSearch.java index 1a0ec205d3..1517e517f6 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoGeoSearch.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/IMogoGeoSearch.java @@ -1,8 +1,9 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; +import com.mogo.map.IDestroyable; import com.mogo.map.exception.MogoMapException; -import com.mogo.map.search.query.MogoGeocodeQuery; -import com.mogo.map.search.query.MogoRegeocodeQuery; +import com.mogo.map.search.geo.query.MogoGeocodeQuery; +import com.mogo.map.search.geo.query.MogoRegeocodeQuery; import java.util.List; @@ -12,7 +13,7 @@ import java.util.List; *

* 地理/逆地理位置搜索 */ -public interface IMogoGeoSearch { +public interface IMogoGeoSearch extends IDestroyable { /** * 添加异步编码回调 @@ -28,6 +29,7 @@ public interface IMogoGeoSearch { * @return * @throws MogoMapException */ + @Deprecated MogoRegeocodeAddress getFromLocation( MogoRegeocodeQuery query ) throws MogoMapException; /** @@ -37,6 +39,7 @@ public interface IMogoGeoSearch { * @return * @throws MogoMapException */ + @Deprecated List< MogoGeocodeAddress > getFromLocationName( MogoGeocodeQuery query ) throws MogoMapException; /** diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoGeoSearchListener.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/IMogoGeoSearchListener.java similarity index 62% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoGeoSearchListener.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/IMogoGeoSearchListener.java index ae1689b236..5f895a7db9 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoGeoSearchListener.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/IMogoGeoSearchListener.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; /** * @author congtaowang @@ -12,15 +12,13 @@ public interface IMogoGeoSearchListener { * 逆地理编码(根据经纬度获取地理位置信息) * * @param regeocodeResult - * @param rCode */ - void onRegeocodeSearched( MogoRegeocodeResult regeocodeResult, int rCode ); + default void onRegeocodeSearched( MogoRegeocodeResult regeocodeResult ){} /** * 根据名称和城市获取地理位置信息 * * @param geocodeResult - * @param i */ - void onGeocodeSearched( MogoGeocodeResult geocodeResult, int i ); + default void onGeocodeSearched( MogoGeocodeResult geocodeResult ){} } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoAoiItem.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoAoiItem.java similarity index 85% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoAoiItem.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoAoiItem.java index e02c987202..98b4c8ef03 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoAoiItem.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoAoiItem.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; @@ -96,4 +96,15 @@ public class MogoAoiItem implements Parcelable { return new MogoAoiItem[size]; } }; + + @Override + public String toString() { + return "MogoAoiItem{" + + "aoiId='" + aoiId + '\'' + + ", aoiName='" + aoiName + '\'' + + ", adCode='" + adCode + '\'' + + ", aoiCenterPoint=" + aoiCenterPoint + + ", aoiArea=" + aoiArea + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoBusinessArea.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoBusinessArea.java similarity index 86% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoBusinessArea.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoBusinessArea.java index b3000a053d..d8e48978e1 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoBusinessArea.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoBusinessArea.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; @@ -63,4 +63,12 @@ public class MogoBusinessArea implements Parcelable { return new MogoBusinessArea[size]; } }; + + @Override + public String toString() { + return "MogoBusinessArea{" + + "centerPoint=" + centerPoint + + ", name='" + name + '\'' + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoCrossroad.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoCrossroad.java similarity index 84% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoCrossroad.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoCrossroad.java index 0fbc560d63..3dcd6ea798 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoCrossroad.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoCrossroad.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; @@ -105,4 +105,16 @@ public class MogoCrossroad implements Parcelable { return new MogoCrossroad[size]; } }; + + @Override + public String toString() { + return "MogoCrossroad{" + + "distance=" + distance + + ", direction='" + direction + '\'' + + ", firstRoadId='" + firstRoadId + '\'' + + ", firstRoadName='" + firstRoadName + '\'' + + ", secondRoadId='" + secondRoadId + '\'' + + ", secondRoadName='" + secondRoadName + '\'' + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoGeocodeAddress.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoGeocodeAddress.java similarity index 75% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoGeocodeAddress.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoGeocodeAddress.java index 09d8700811..f92f294de2 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoGeocodeAddress.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoGeocodeAddress.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import com.mogo.map.MogoLatLng; @@ -100,4 +100,20 @@ public class MogoGeocodeAddress { public void setLevel( String level ) { this.level = level; } + + @Override + public String toString() { + return "MogoGeocodeAddress{" + + "formatAddress='" + formatAddress + '\'' + + ", province='" + province + '\'' + + ", city='" + city + '\'' + + ", district='" + district + '\'' + + ", township='" + township + '\'' + + ", neighborhood='" + neighborhood + '\'' + + ", building='" + building + '\'' + + ", adcode='" + adcode + '\'' + + ", latlng=" + latlng + + ", level='" + level + '\'' + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoGeocodeResult.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoGeocodeResult.java similarity index 70% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoGeocodeResult.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoGeocodeResult.java index ecc855c190..004bdda363 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoGeocodeResult.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoGeocodeResult.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import java.util.ArrayList; import java.util.List; @@ -20,4 +20,11 @@ public class MogoGeocodeResult { public void setAddresses( List< MogoGeocodeAddress > addresses ) { this.addresses = addresses; } + + @Override + public String toString() { + return "MogoGeocodeResult{" + + "addresses=" + addresses + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoIndoorData.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoIndoorData.java similarity index 85% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoIndoorData.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoIndoorData.java index 69ffd1200a..bae861260a 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoIndoorData.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoIndoorData.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; @@ -72,4 +72,13 @@ public class MogoIndoorData implements Parcelable { return new MogoIndoorData[size]; } }; + + @Override + public String toString() { + return "MogoIndoorData{" + + "poiId='" + poiId + '\'' + + ", floor=" + floor + + ", floorName='" + floorName + '\'' + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoPhoto.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoPhoto.java similarity index 84% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoPhoto.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoPhoto.java index feffddf23f..88f3b38427 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoPhoto.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoPhoto.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; @@ -61,4 +61,12 @@ public class MogoPhoto implements Parcelable { return new MogoPhoto[size]; } }; + + @Override + public String toString() { + return "MogoPhoto{" + + "title='" + title + '\'' + + ", url='" + url + '\'' + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoPoiItem.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoPoiItem.java similarity index 85% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoPoiItem.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoPoiItem.java index 22de089a44..27ed374472 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoPoiItem.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoPoiItem.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; @@ -352,4 +352,38 @@ public class MogoPoiItem implements Parcelable { return new MogoPoiItem[size]; } }; + + @Override + public String toString() { + return "MogoPoiItem{" + + "businessArea='" + businessArea + '\'' + + ", adName='" + adName + '\'' + + ", cityName='" + cityName + '\'' + + ", provinceName='" + provinceName + '\'' + + ", typeDes='" + typeDes + '\'' + + ", tel='" + tel + '\'' + + ", adCode='" + adCode + '\'' + + ", poiId='" + poiId + '\'' + + ", distance=" + distance + + ", title='" + title + '\'' + + ", snippet='" + snippet + '\'' + + ", point=" + point + + ", cityCode='" + cityCode + '\'' + + ", enter=" + enter + + ", exit=" + exit + + ", website='" + website + '\'' + + ", postcode='" + postcode + '\'' + + ", email='" + email + '\'' + + ", direction='" + direction + '\'' + + ", indoorMap=" + indoorMap + + ", provinceCode='" + provinceCode + '\'' + + ", parkingType='" + parkingType + '\'' + + ", subPois=" + subPois + + ", indoorData=" + indoorData + + ", photos=" + photos + + ", poiExtension=" + poiExtension + + ", typeCode='" + typeCode + '\'' + + ", shopID='" + shopID + '\'' + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoPoiItemExtension.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoPoiItemExtension.java similarity index 97% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoPoiItemExtension.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoPoiItemExtension.java index 645b91c6bb..3e19a49f32 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoPoiItemExtension.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoPoiItemExtension.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoRegeocodeAddress.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoRegeocodeAddress.java similarity index 86% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoRegeocodeAddress.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoRegeocodeAddress.java index b3d90e6556..2026ac051a 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoRegeocodeAddress.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoRegeocodeAddress.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; @@ -228,4 +228,27 @@ public class MogoRegeocodeAddress implements Parcelable { return new MogoRegeocodeAddress[size]; } }; + + @Override + public String toString() { + return "MogoRegeocodeAddress{" + + "formatAddress='" + formatAddress + '\'' + + ", province='" + province + '\'' + + ", city='" + city + '\'' + + ", cityCode='" + cityCode + '\'' + + ", adCode='" + adCode + '\'' + + ", district='" + district + '\'' + + ", township='" + township + '\'' + + ", neighborhood='" + neighborhood + '\'' + + ", building='" + building + '\'' + + ", streetNumber=" + streetNumber + + ", roads=" + roads + + ", pois=" + pois + + ", crossroads=" + crossroads + + ", businessAreas=" + businessAreas + + ", aois=" + aois + + ", towncode='" + towncode + '\'' + + ", country='" + country + '\'' + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoRegeocodeResult.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoRegeocodeResult.java similarity index 86% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoRegeocodeResult.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoRegeocodeResult.java index 6fd7141374..1c2bcca713 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoRegeocodeResult.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoRegeocodeResult.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; @@ -50,4 +50,11 @@ public class MogoRegeocodeResult implements Parcelable { return new MogoRegeocodeResult[size]; } }; + + @Override + public String toString() { + return "MogoRegeocodeResult{" + + "regeocodeAddress=" + regeocodeAddress + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoRegeocodeRoad.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoRegeocodeRoad.java similarity index 85% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoRegeocodeRoad.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoRegeocodeRoad.java index d3fb6c2ece..59b32cbcf2 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoRegeocodeRoad.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoRegeocodeRoad.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; @@ -95,4 +95,15 @@ public class MogoRegeocodeRoad implements Parcelable { return new MogoRegeocodeRoad[size]; } }; + + @Override + public String toString() { + return "MogoRegeocodeRoad{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", distance=" + distance + + ", direction='" + direction + '\'' + + ", point=" + point + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoStreetNumber.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoStreetNumber.java similarity index 85% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoStreetNumber.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoStreetNumber.java index c12d20fbaf..c026129e36 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoStreetNumber.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoStreetNumber.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; @@ -95,4 +95,15 @@ public class MogoStreetNumber implements Parcelable { return new MogoStreetNumber[size]; } }; + + @Override + public String toString() { + return "MogoStreetNumber{" + + "street='" + street + '\'' + + ", number='" + number + '\'' + + ", latLonPoint=" + latLonPoint + + ", direction='" + direction + '\'' + + ", distance=" + distance + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoSubPoiItem.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoSubPoiItem.java similarity index 85% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoSubPoiItem.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoSubPoiItem.java index f1240ef0ee..b43ff95317 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoSubPoiItem.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/MogoSubPoiItem.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.geo; import android.os.Parcel; import android.os.Parcelable; @@ -118,4 +118,17 @@ public class MogoSubPoiItem implements Parcelable { return new MogoSubPoiItem[size]; } }; + + @Override + public String toString() { + return "MogoSubPoiItem{" + + "poiId='" + poiId + '\'' + + ", title='" + title + '\'' + + ", subName='" + subName + '\'' + + ", distance=" + distance + + ", point=" + point + + ", snippet='" + snippet + '\'' + + ", subTypeDes='" + subTypeDes + '\'' + + '}'; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/query/MogoGeocodeQuery.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/query/MogoGeocodeQuery.java similarity index 97% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/query/MogoGeocodeQuery.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/query/MogoGeocodeQuery.java index 441bd20bad..988533cc5f 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/query/MogoGeocodeQuery.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/query/MogoGeocodeQuery.java @@ -1,4 +1,4 @@ -package com.mogo.map.search.query; +package com.mogo.map.search.geo.query; import android.os.Parcel; import android.os.Parcelable; diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/query/MogoRegeocodeQuery.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/query/MogoRegeocodeQuery.java similarity index 91% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/query/MogoRegeocodeQuery.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/query/MogoRegeocodeQuery.java index cd295d404a..ea5bf42895 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/query/MogoRegeocodeQuery.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/geo/query/MogoRegeocodeQuery.java @@ -1,4 +1,4 @@ -package com.mogo.map.search.query; +package com.mogo.map.search.geo.query; import android.os.Parcel; import android.os.Parcelable; @@ -14,7 +14,7 @@ import com.mogo.map.MogoLatLng; public class MogoRegeocodeQuery implements Parcelable { private MogoLatLng point; - private float radius; + private int radius; private String latlngType; private String poiType; @@ -26,11 +26,11 @@ public class MogoRegeocodeQuery implements Parcelable { this.point = point; } - public float getRadius() { + public int getRadius() { return radius; } - public void setRadius( float radius ) { + public void setRadius( int radius ) { this.radius = radius; } @@ -69,7 +69,7 @@ public class MogoRegeocodeQuery implements Parcelable { protected MogoRegeocodeQuery( Parcel in ) { this.point = in.readParcelable( MogoLatLng.class.getClassLoader() ); - this.radius = in.readFloat(); + this.radius = in.readInt(); this.latlngType = in.readString(); this.poiType = in.readString(); } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoInputtipsListener.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/IMogoInputtipsListener.java similarity index 60% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoInputtipsListener.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/IMogoInputtipsListener.java index 1cba147ba2..76dffd78bd 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoInputtipsListener.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/IMogoInputtipsListener.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.inputtips; import java.util.List; @@ -10,5 +10,5 @@ import java.util.List; */ public interface IMogoInputtipsListener { - void onGetInputtips( List< MogoTip > result, int code ); + void onGetInputtips( List< MogoTip > result ); } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoInputtipsSearch.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/IMogoInputtipsSearch.java similarity index 59% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoInputtipsSearch.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/IMogoInputtipsSearch.java index 0d7701e90d..29ac55bd09 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/IMogoInputtipsSearch.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/IMogoInputtipsSearch.java @@ -1,7 +1,8 @@ -package com.mogo.map.search; +package com.mogo.map.search.inputtips; +import com.mogo.map.IDestroyable; import com.mogo.map.exception.MogoMapException; -import com.mogo.map.search.query.MogoInputtipsQuery; +import com.mogo.map.search.inputtips.query.MogoInputtipsQuery; import java.util.List; @@ -11,14 +12,12 @@ import java.util.List; *

* 描述 */ -public interface IMogoInputtipsSearch { +public interface IMogoInputtipsSearch extends IDestroyable { void setQuery( MogoInputtipsQuery query ); void setInputtipsListener( IMogoInputtipsListener listener ); void requestInputtipsAsyn(); - - List< MogoTip > requestInputtips() throws MogoMapException; } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoTip.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/MogoTip.java similarity index 98% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoTip.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/MogoTip.java index 1f6c631c2a..26aeb8de5d 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoTip.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/MogoTip.java @@ -1,4 +1,4 @@ -package com.mogo.map.search; +package com.mogo.map.search.inputtips; import android.os.Parcel; import android.os.Parcelable; diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/query/MogoInputtipsQuery.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/query/MogoInputtipsQuery.java similarity index 95% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/query/MogoInputtipsQuery.java rename to libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/query/MogoInputtipsQuery.java index 7267328d81..16e10de6bc 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/query/MogoInputtipsQuery.java +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/inputtips/query/MogoInputtipsQuery.java @@ -1,4 +1,4 @@ -package com.mogo.map.search.query; +package com.mogo.map.search.inputtips.query; import com.mogo.map.MogoLatLng; diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/IMogoPoiSearch.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/IMogoPoiSearch.java new file mode 100644 index 0000000000..e291931fb5 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/IMogoPoiSearch.java @@ -0,0 +1,58 @@ +package com.mogo.map.search.poisearch; + +import com.mogo.map.IDestroyable; +import com.mogo.map.exception.MogoMapException; +import com.mogo.map.search.geo.MogoPoiItem; +import com.mogo.map.search.poisearch.query.MogoPoiSearchQuery; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * poi 搜索 + */ +public interface IMogoPoiSearch extends IDestroyable { + + void setPoiSearchListener( IMogoPoiSearchListener listener ); + + /** + * 异步搜索poi信息 + */ + void searchPOIAsyn(); + + /** + * 同步搜索poi信息 + * + * @return + */ + MogoPoiResult searchPOI() throws MogoMapException; + + /** + * 设置查询条件 + * + * @param query + */ + void setQuery( MogoPoiSearchQuery query ); + + /** + * 根据poiId搜索详情,同步 + * + * @param poiId + * @return + */ + MogoPoiItem searchPOIId( String poiId ) throws MogoMapException; + + /** + * 根据poiId搜索详情,异步 + * + * @param poiId + */ + void searchPOIIdAsyn( String poiId ); + + /** + * 周边检索POI + * + * @param bound + */ + void setBound( MogoSearchBound bound ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/IMogoPoiSearchListener.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/IMogoPoiSearchListener.java new file mode 100644 index 0000000000..7a8cffa543 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/IMogoPoiSearchListener.java @@ -0,0 +1,22 @@ +package com.mogo.map.search.poisearch; + +import com.mogo.map.search.geo.MogoPoiItem; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * poi 检索结果回调 + */ +public interface IMogoPoiSearchListener { + + /** + * 返回POI搜索异步处理的结果。 + */ + void onPoiSearched( MogoPoiResult result, int errorCode ); + + /** + * poi ID 检索结果回调方法 + */ + void onPoiItemSearched( MogoPoiItem item, int errorCode ); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/MogoPoiResult.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/MogoPoiResult.java new file mode 100644 index 0000000000..3fbf846c8c --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/MogoPoiResult.java @@ -0,0 +1,24 @@ +package com.mogo.map.search.poisearch; + +import com.mogo.map.search.geo.MogoPoiItem; + +import java.util.ArrayList; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * poi搜索结果集 + */ +public class MogoPoiResult { + + private ArrayList< MogoPoiItem > pois; + + public ArrayList< MogoPoiItem > getPois() { + return pois; + } + + public void setPois( ArrayList< MogoPoiItem > pois ) { + this.pois = pois; + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/MogoSearchBound.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/MogoSearchBound.java new file mode 100644 index 0000000000..773ae1b650 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/MogoSearchBound.java @@ -0,0 +1,142 @@ +package com.mogo.map.search.poisearch; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.mogo.map.MogoLatLng; + +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * 周边搜索范围 + */ +public class MogoSearchBound implements Parcelable { + + public static final String SHAPE_BOUND = "Bound"; + public static final String SHAPE_RECTANGLE = "Rectangle"; + public static final String SHAPE_POLYGON = "Polygon"; + + /** + * 中心点 + */ + private MogoLatLng centerPoint; + /** + * 半径:米 + */ + private int radiusInMeters; + + /** + * 搜索范围的形状 + */ + private String shape; + + /** + * 按距离排序 + */ + private boolean isDistanceSort; + + /** + * 左下角 + */ + private MogoLatLng lowerLeft; + /** + * 右上角 + */ + private MogoLatLng upperRight; + + /** + * 范围搜索地点列表 + */ + private List< MogoLatLng > polyGonList; + + public MogoSearchBound( MogoLatLng centerPoint, int radiusInMeters ) { + this( centerPoint, radiusInMeters, true ); + } + + public MogoSearchBound( MogoLatLng centerPoint, int radiusInMeters, boolean isDistanceSort ) { + this.centerPoint = centerPoint; + this.radiusInMeters = radiusInMeters; + this.isDistanceSort = isDistanceSort; + this.shape = SHAPE_BOUND; + } + + public MogoSearchBound( MogoLatLng lowerLeft, MogoLatLng upperRight ) { + this.lowerLeft = lowerLeft; + this.upperRight = upperRight; + this.shape = SHAPE_RECTANGLE; + } + + public MogoSearchBound( List< MogoLatLng > polyGonList ) { + this.polyGonList = polyGonList; + this.shape = SHAPE_POLYGON; + } + + public MogoLatLng getCenterPoint() { + return centerPoint; + } + + public int getRadiusInMeters() { + return radiusInMeters; + } + + public String getShape() { + return shape; + } + + public boolean isDistanceSort() { + return isDistanceSort; + } + + public MogoLatLng getLowerLeft() { + return lowerLeft; + } + + public MogoLatLng getUpperRight() { + return upperRight; + } + + public List< MogoLatLng > getPolyGonList() { + return polyGonList; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel( Parcel dest, int flags ) { + dest.writeParcelable( this.centerPoint, flags ); + dest.writeInt( this.radiusInMeters ); + dest.writeString( this.shape ); + dest.writeByte( this.isDistanceSort ? ( byte ) 1 : ( byte ) 0 ); + dest.writeParcelable( this.lowerLeft, flags ); + dest.writeParcelable( this.upperRight, flags ); + dest.writeTypedList( this.polyGonList ); + } + + protected MogoSearchBound( Parcel in ) { + this.centerPoint = in.readParcelable( MogoLatLng.class.getClassLoader() ); + this.radiusInMeters = in.readInt(); + this.shape = in.readString(); + this.isDistanceSort = in.readByte() != 0; + this.lowerLeft = in.readParcelable( MogoLatLng.class.getClassLoader() ); + this.upperRight = in.readParcelable( MogoLatLng.class.getClassLoader() ); + this.polyGonList = in.createTypedArrayList( MogoLatLng.CREATOR ); + } + + public static final Parcelable.Creator< MogoSearchBound > CREATOR = new Parcelable.Creator< MogoSearchBound >() { + @Override + public MogoSearchBound createFromParcel( Parcel source ) { + return new MogoSearchBound( source ); + } + + @Override + public MogoSearchBound[] newArray( int size ) { + return new MogoSearchBound[size]; + } + }; +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/query/MogoPoiSearchQuery.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/query/MogoPoiSearchQuery.java new file mode 100644 index 0000000000..b3b539fca3 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/search/poisearch/query/MogoPoiSearchQuery.java @@ -0,0 +1,159 @@ +package com.mogo.map.search.poisearch.query; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.mogo.map.MogoLatLng; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * poi 搜索查询条件 + */ +public class MogoPoiSearchQuery implements Parcelable { + + private String query; + private String category; + private String city; + private String building; + private int pageNum; + private int pageSize; + private boolean isCityLimit; + private boolean isSubPois; + private boolean isDistanceSort = true; + private MogoLatLng location; + + /** + * @param query 查询字符串,多个关键字用“|”分割 + * @param category 类型的组合,比如定义如下组合:餐馆|电影院|景点 + */ + public MogoPoiSearchQuery( String query, String category ) { + this.query = query; + this.category = category; + this.city = null; + } + + /** + * @param query 查询字符串,多个关键字用“|”分割 + * @param category 类型的组合,比如定义如下组合:餐馆|电影院|景点 + */ + public MogoPoiSearchQuery( String query, String category, String city ) { + this.query = query; + this.category = category; + this.city = city; + } + + public String getBuilding() { + return building; + } + + public void setBuilding( String building ) { + this.building = building; + } + + public String getQuery() { + return query; + } + + public String getCategory() { + return category; + } + + public String getCity() { + return city; + } + + public int getPageNum() { + return pageNum; + } + + public void setPageNum( int pageNum ) { + this.pageNum = pageNum; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize( int pageSize ) { + this.pageSize = pageSize; + } + + public boolean isCityLimit() { + return isCityLimit; + } + + public void setCityLimit( boolean cityLimit ) { + isCityLimit = cityLimit; + } + + public boolean isSubPois() { + return isSubPois; + } + + public void setSubPois( boolean subPois ) { + isSubPois = subPois; + } + + public boolean isDistanceSort() { + return isDistanceSort; + } + + public void setDistanceSort( boolean distanceSort ) { + isDistanceSort = distanceSort; + } + + public MogoLatLng getLocation() { + return location; + } + + public void setLocation( MogoLatLng location ) { + this.location = location; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel( Parcel dest, int flags ) { + dest.writeString( this.building ); + dest.writeString( this.category ); + dest.writeString( this.city ); + dest.writeInt( this.pageNum ); + dest.writeInt( this.pageSize ); + dest.writeByte( this.isCityLimit ? ( byte ) 1 : ( byte ) 0 ); + dest.writeByte( this.isSubPois ? ( byte ) 1 : ( byte ) 0 ); + dest.writeByte( this.isDistanceSort ? ( byte ) 1 : ( byte ) 0 ); + dest.writeParcelable( this.location, flags ); + } + + public MogoPoiSearchQuery() { + } + + protected MogoPoiSearchQuery( Parcel in ) { + this.building = in.readString(); + this.category = in.readString(); + this.city = in.readString(); + this.pageNum = in.readInt(); + this.pageSize = in.readInt(); + this.isCityLimit = in.readByte() != 0; + this.isSubPois = in.readByte() != 0; + this.isDistanceSort = in.readByte() != 0; + this.location = in.readParcelable( MogoLatLng.class.getClassLoader() ); + } + + public static final Parcelable.Creator< MogoPoiSearchQuery > CREATOR = new Parcelable.Creator< MogoPoiSearchQuery >() { + @Override + public MogoPoiSearchQuery createFromParcel( Parcel source ) { + return new MogoPoiSearchQuery( source ); + } + + @Override + public MogoPoiSearchQuery[] newArray( int size ) { + return new MogoPoiSearchQuery[size]; + } + }; +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/CarCursorOption.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/CarCursorOption.java new file mode 100644 index 0000000000..86e8432f7e --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/CarCursorOption.java @@ -0,0 +1,125 @@ +package com.mogo.map.uicontroller; + +import android.graphics.Bitmap; + +import androidx.annotation.DrawableRes; + +import com.mogo.map.IDestroyable; + +/** + * @author congtaowang + * @since 2020-04-13 + *

+ * 设置自车图标 + */ +public class CarCursorOption implements Cloneable, IDestroyable { + + private CarCursorOption() { + } + + /** + * 自车图标资源 + */ + @DrawableRes + private int mCarCursorRes = 0; + + /** + * 自车图标图片,优先使用 + */ + private Bitmap mCarCursorBmp; + + /** + * 导航图标资源 + */ + @DrawableRes + private int mNaviCursorRes = 0; + + public int getCarCursorRes() { + return mCarCursorRes; + } + + public void setCarCursorRes( int carCursorRes ) { + this.mCarCursorRes = carCursorRes; + } + + public Bitmap getCarCursorBmp() { + return mCarCursorBmp; + } + + public void setCarCursorBmp( Bitmap carCursorBmp ) { + this.mCarCursorBmp = carCursorBmp; + } + + public int getNaviCursorRes() { + return mNaviCursorRes; + } + + public void setNaviCursorRes( int naviCursorRes ) { + this.mNaviCursorRes = naviCursorRes; + } + + public static class Builder { + + private CarCursorOption target; + + public Builder() { + target = new CarCursorOption(); + } + + /** + * 自车图标资源 + */ + public Builder carCursorRes( @DrawableRes int redId ) { + target.mCarCursorRes = redId; + return this; + } + + /** + * 自车图标图片,优先使用 + */ + public Builder carCursorBmp( Bitmap bmp ) { + target.mCarCursorBmp = bmp; + return this; + } + + /** + * 导航图标资源 + * + * @param naviCursorRes + * @return + */ + public Builder naviCursorRes( int naviCursorRes ) { + target.mNaviCursorRes = naviCursorRes; + return this; + } + + public CarCursorOption build() { + return target; + } + } + + @Override + public CarCursorOption clone() throws CloneNotSupportedException { + CarCursorOption option = ( CarCursorOption ) super.clone(); + if ( mCarCursorBmp != null && !mCarCursorBmp.isRecycled() ) { + try { + option.mCarCursorBmp = Bitmap.createBitmap( mCarCursorBmp ); + } catch ( Exception e ) { + option.mCarCursorBmp = null; + } + } + option.mCarCursorRes = mCarCursorRes; + option.mNaviCursorRes = mNaviCursorRes; + return option; + } + + @Override + public void destroy() { + if ( mCarCursorBmp != null && !mCarCursorBmp.isRecycled() ) { + mCarCursorBmp.recycle(); + } + mCarCursorBmp = null; + mCarCursorRes = 0; + mNaviCursorRes = 0; + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/EnumMapUI.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/EnumMapUI.java new file mode 100644 index 0000000000..bae12fe5a7 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/EnumMapUI.java @@ -0,0 +1,56 @@ +package com.mogo.map.uicontroller; + +/** + * @author congtaowang + * @since 2019-12-26 + *

+ * 地图样式 + */ +public enum EnumMapUI { + + /** + * 正北朝上2D + */ + NorthUP_2D( 0, 1 ), + /** + * 车头朝上2D + */ + CarUp_2D( 1, 2 ), + + /** + * 3D,只能头朝上 + */ + CarUp_3D( 2, 0 ), + + /** + * 白天模式 + */ + Type_Light( 3, 5 ), + + /** + * 夜晚模式 + */ + Type_Night( 4, 4 ), + + /** + * 夜晚模式 + */ + Type_AUTO_LIGHT_Night( 5, 3 ); + + private int next; + private int code; + + EnumMapUI( int code, int next ) { + this.code = code; + this.next = next; + } + + public EnumMapUI next() { + for ( EnumMapUI value : EnumMapUI.values() ) { + if ( value.code == next ) { + return value; + } + } + return this; + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/IMogoMapUIController.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/IMogoMapUIController.java new file mode 100644 index 0000000000..419f4cc00a --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/IMogoMapUIController.java @@ -0,0 +1,226 @@ +package com.mogo.map.uicontroller; + +import android.graphics.Point; +import android.graphics.Rect; +import android.location.Location; +import android.view.View; +import android.view.animation.Interpolator; + +import androidx.annotation.DrawableRes; +import androidx.annotation.Nullable; + +import com.mogo.map.MogoLatLng; +import com.mogo.map.marker.IMogoMarker; +import com.mogo.map.marker.anim.OnMarkerAnimationListener; + +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-26 + *

+ * 地图UI控制 + */ +public interface IMogoMapUIController { + + /** + * 实时路况 + */ + void setTrafficEnabled( boolean visible ); + + /** + * 地图缩放 + * + * @param zoomIn true - 放大 false - 缩小 + */ + MapControlResult changeZoom( boolean zoomIn ); + + /** + * 修改缩放级别 + */ + MapControlResult changeZoom( float zoom ); + + /** + * 切换2D/3D模式 + * + * @param mode true - 3D模式 false - 2D模式 + */ + void changeMapMode( EnumMapUI mode ); + + /** + * 将地图移动至当前位置 + */ + default void moveToCenter( MogoLatLng latLng ){ + moveToCenter(latLng, false); + } + + /** + * 将地图移动至当前位置 + */ + void moveToCenter( MogoLatLng latLng, boolean animate ); + + /** + * 显示我的位置 + * + * @param visible true - 显示 false - 不显示 + */ + void showMyLocation( boolean visible ); + + /** + * @param view + */ + void showMyLocation( View view ); + + /** + * 以外部定位的方式改变当前位置 + * + * @param location + */ + void changeMyLocation( Location location ); + + /** + * 锁车 + */ + void recoverLockMode(); + + /** + * 解锁锁车 + */ + void loseLockMode(); + + /** + * 设置锁车缩放级别 + * + * @param var1 级别 3-20 + */ + void setLockZoom( int var1 ); + + /** + * 预览全程 + * + * @param bounds 显示范围 + */ + void displayOverview( Rect bounds ); + + /** + * 获取比例尺数据 + * + * @return 当前缩放级别下,地图上1像素点对应的长度,单位米 + */ + float getScalePerPixel(); + + /** + * 获取缩放比例 + */ + float getZoomLevel(); + + /** + * 获取视图东北角坐标 + */ + MogoLatLng getCameraNorthEastPosition(); + + /** + * 获取视图西南角坐标 + */ + MogoLatLng getCameraSouthWestPosition(); + + /** + * 获取视图中心点坐标 + */ + MogoLatLng getWindowCenterLocation(); + + /** + * 设置地图中心点 + * + * @param mapCenterX x 点位置x值与地图宽度的比例 + * @param mapCenterY y 点位置x值与地图高度的比例 + */ + void setPointToCenter( double mapCenterX, double mapCenterY ); + + /** + * 获取经纬度对应的屏幕的位置 + */ + Point getLocationPointInScreen( MogoLatLng latLng ); + + /** + * 获取像素点对应的经纬度 + */ + MogoLatLng getLocationMogoLatLngInScreen( Point point ); + + /** + * marker 跳跃动画 + *

+ * Deprecated, instead of by {@link IMogoMarker#startJumpAnimation(float, long, Interpolator, OnMarkerAnimationListener)} + * + * @param marker 跳跃的 marker + * @param high 跳跃的高度 + * @param interpolator 插值器 + * @param duration 动画时间 + */ + @Deprecated + void startJumpAnimation( IMogoMarker marker, float high, Interpolator interpolator, + long duration ); + + /** + * 设置刷新帧率 + */ + void setRenderFps( int fps ); + + /** + * @param tag 调用业务 + * @param carPosition 当前位置 + * @param lonLats 经纬度围成的范围 + * @param bound 地图上可显示的范围 + * @param lockCarPosition 是否锁定车辆位置 + */ + void showBounds( String tag, MogoLatLng carPosition, List< MogoLatLng > lonLats, Rect bound, boolean lockCarPosition ); + + /** + * 强制刷新地图 + */ + void forceRender(); + + /** + * 计算两点之间的距离 + * + * @param p1 + * @param p2 + * @return + */ + float calculateLineDistance( MogoLatLng p1, MogoLatLng p2 ) throws Exception; + + /** + * 当前的视图模式 + * + * @return + */ + EnumMapUI getCurrentUiMode(); + + /** + * 锁车状态 + * + * @return + */ + boolean isCarLocked(); + + /** + * 配置自车图标样式 + * + * @param option 为空时使用 + * 默认配置 + */ + void setCarCursorOption( @Nullable CarCursorOption option ); + + /** + * 获取地图视图描述快照 + * + * @return + */ + MapCameraPosition getMapCameraPosition(); + + /** + * 切换地图视图视角 + * @param bearing + */ + void changeBearing(float bearing); +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/MapCameraPosition.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/MapCameraPosition.java new file mode 100644 index 0000000000..52ea00bfad --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/MapCameraPosition.java @@ -0,0 +1,40 @@ +package com.mogo.map.uicontroller; + +import com.mogo.map.MogoLatLng; + +/** + * @author congtaowang + * @since 2020-04-26 + *

+ * 地图视图描述 + */ +public class MapCameraPosition { + + private final MogoLatLng mLonLat; + private final float mBearing; + private final float mTilt; + private final float mZoom; + + public MapCameraPosition( MogoLatLng lonLat, float bearing, float tilt, float zoom ) { + this.mLonLat = lonLat; + this.mBearing = bearing; + this.mTilt = tilt; + this.mZoom = zoom; + } + + public MogoLatLng getLonLat() { + return mLonLat; + } + + public float getBearing() { + return mBearing; + } + + public float getTilt() { + return mTilt; + } + + public float getZoom() { + return mZoom; + } +} diff --git a/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/MapControlResult.java b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/MapControlResult.java new file mode 100644 index 0000000000..8735d80033 --- /dev/null +++ b/libraries/mogo-map-api/src/main/java/com/mogo/map/uicontroller/MapControlResult.java @@ -0,0 +1,30 @@ +package com.mogo.map.uicontroller; + +/** + * @author congtaowang + * @since 2020-04-01 + *

+ * 地图控制结果 + */ +public enum MapControlResult { + + /** + * 成功 + */ + SUCCESS, + + /** + * 当前已经为预期结果 + */ + TARGET, + + /** + * 失败 + */ + FAIL, + + /** + * 错误,未执行 + */ + ERROR +} diff --git a/libraries/mogo-map-api/src/main/res/drawable-ldpi/ic_amap_navi_cursor.png b/libraries/mogo-map-api/src/main/res/drawable-ldpi/ic_amap_navi_cursor.png new file mode 100644 index 0000000000..6957c2c84c Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-ldpi/ic_amap_navi_cursor.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-ldpi/ic_navi_start.png b/libraries/mogo-map-api/src/main/res/drawable-ldpi/ic_navi_start.png new file mode 100644 index 0000000000..32454791f8 Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-ldpi/ic_navi_start.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-ldpi/ic_navi_target.png b/libraries/mogo-map-api/src/main/res/drawable-ldpi/ic_navi_target.png new file mode 100644 index 0000000000..8669793958 Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-ldpi/ic_navi_target.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-ldpi/map_api_ic_current_location2.png b/libraries/mogo-map-api/src/main/res/drawable-ldpi/map_api_ic_current_location2.png new file mode 100644 index 0000000000..5d2d79c7e5 Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-ldpi/map_api_ic_current_location2.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-mdpi/ic_amap_navi_cursor.png b/libraries/mogo-map-api/src/main/res/drawable-mdpi/ic_amap_navi_cursor.png new file mode 100644 index 0000000000..6957c2c84c Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-mdpi/ic_amap_navi_cursor.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-mdpi/ic_navi_start.png b/libraries/mogo-map-api/src/main/res/drawable-mdpi/ic_navi_start.png new file mode 100644 index 0000000000..32454791f8 Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-mdpi/ic_navi_start.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-mdpi/ic_navi_target.png b/libraries/mogo-map-api/src/main/res/drawable-mdpi/ic_navi_target.png new file mode 100644 index 0000000000..8669793958 Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-mdpi/ic_navi_target.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-mdpi/map_api_ic_current_location2.png b/libraries/mogo-map-api/src/main/res/drawable-mdpi/map_api_ic_current_location2.png new file mode 100644 index 0000000000..5d2d79c7e5 Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-mdpi/map_api_ic_current_location2.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-xhdpi-1920x1000/map_api_ic_current_location2.png b/libraries/mogo-map-api/src/main/res/drawable-xhdpi-1920x1000/map_api_ic_current_location2.png new file mode 100644 index 0000000000..06fb9a934e Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-xhdpi-1920x1000/map_api_ic_current_location2.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-xhdpi/ic_amap_navi_cursor.png b/libraries/mogo-map-api/src/main/res/drawable-xhdpi/ic_amap_navi_cursor.png new file mode 100755 index 0000000000..fce07ecf01 Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-xhdpi/ic_amap_navi_cursor.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-xhdpi/ic_navi_start.png b/libraries/mogo-map-api/src/main/res/drawable-xhdpi/ic_navi_start.png new file mode 100644 index 0000000000..addc3b5e8d Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-xhdpi/ic_navi_start.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-xhdpi/ic_navi_target.png b/libraries/mogo-map-api/src/main/res/drawable-xhdpi/ic_navi_target.png new file mode 100644 index 0000000000..75a0dbba0c Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-xhdpi/ic_navi_target.png differ diff --git a/libraries/mogo-map-api/src/main/res/drawable-xhdpi/map_api_ic_current_location2.png b/libraries/mogo-map-api/src/main/res/drawable-xhdpi/map_api_ic_current_location2.png new file mode 100644 index 0000000000..c24c56f3db Binary files /dev/null and b/libraries/mogo-map-api/src/main/res/drawable-xhdpi/map_api_ic_current_location2.png differ diff --git a/libraries/mogo-map-api/src/main/res/values/strings.xml b/libraries/mogo-map-api/src/main/res/values/strings.xml new file mode 100644 index 0000000000..95cfda1d0d --- /dev/null +++ b/libraries/mogo-map-api/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + mogo-map-api + diff --git a/libraries/mogo-map/build.gradle b/libraries/mogo-map/build.gradle index 545771335c..6cfbecae4f 100644 --- a/libraries/mogo-map/build.gradle +++ b/libraries/mogo-map/build.gradle @@ -1,15 +1,13 @@ apply plugin: 'com.android.library' android { - compileSdkVersion 29 - buildToolsVersion "29.0.2" - - + compileSdkVersion rootProject.ext.android.compileSdkVersion + // buildToolsVersion rootProject.ext.android.buildToolsVersion defaultConfig { - minSdkVersion 19 - targetSdkVersion 29 - versionCode 1 - versionName "1.0" + minSdkVersion rootProject.ext.android.minSdkVersion + targetSdkVersion rootProject.ext.android.targetSdkVersion + versionCode Integer.valueOf(VERSION_CODE) + versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION") testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' @@ -21,15 +19,25 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } - } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation rootProject.ext.dependencies.androidxappcompat - implementation rootProject.ext.dependencies.amapnavi3dmap - implementation rootProject.ext.dependencies.amapsearch - implementation rootProject.ext.dependencies.amaplocation - implementation project(':foudations:mogo-utils') + if (Boolean.valueOf(RELEASE)) { + implementation rootProject.ext.dependencies.mogoutils + implementation rootProject.ext.dependencies.mogomapapi + api rootProject.ext.dependencies.mapamap + api rootProject.ext.dependencies.mapautomap + implementation rootProject.ext.dependencies.mogocommons + } else { + implementation project(':foudations:mogo-utils') + implementation project(':libraries:mogo-map-api') + api project(':libraries:map-amap') + api project(':libraries:map-autonavi') + implementation project(':foudations:mogo-commons') + } } + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() diff --git a/libraries/mogo-map/consumer-rules.pro b/libraries/mogo-map/consumer-rules.pro index e69de29bb2..a742829747 100644 --- a/libraries/mogo-map/consumer-rules.pro +++ b/libraries/mogo-map/consumer-rules.pro @@ -0,0 +1,4 @@ +#-----MogoMap----- +-keep class com.mogo.map.MogoNavi{ + private (); +} \ No newline at end of file diff --git a/libraries/mogo-map/gradle.properties b/libraries/mogo-map/gradle.properties new file mode 100644 index 0000000000..6c52acbe41 --- /dev/null +++ b/libraries/mogo-map/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.map +POM_ARTIFACT_ID=mogo-map +VERSION_CODE=1 diff --git a/libraries/mogo-map/proguard-rules.pro b/libraries/mogo-map/proguard-rules.pro index f1b424510d..f10712073b 100644 --- a/libraries/mogo-map/proguard-rules.pro +++ b/libraries/mogo-map/proguard-rules.pro @@ -19,3 +19,8 @@ # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile + +#-----MogoMap----- +-keep class com.mogo.map.MogoNavi{ + private (); +} diff --git a/libraries/mogo-map/src/main/AndroidManifest.xml b/libraries/mogo-map/src/main/AndroidManifest.xml index cfaf88eee3..d8de0aa4b3 100644 --- a/libraries/mogo-map/src/main/AndroidManifest.xml +++ b/libraries/mogo-map/src/main/AndroidManifest.xml @@ -1,2 +1,20 @@ + package="com.mogo.map"> + + + + + + + + + + + + + + + + + + diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoGeoSearch.java b/libraries/mogo-map/src/main/java/com/mogo/map/MogoGeoSearch.java similarity index 72% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoGeoSearch.java rename to libraries/mogo-map/src/main/java/com/mogo/map/MogoGeoSearch.java index 6d7c509b61..b67c1c4086 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoGeoSearch.java +++ b/libraries/mogo-map/src/main/java/com/mogo/map/MogoGeoSearch.java @@ -1,11 +1,15 @@ -package com.mogo.map.search; +package com.mogo.map; import android.content.Context; -import com.mogo.map.amap.search.GeocodeSearchClient; import com.mogo.map.exception.MogoMapException; -import com.mogo.map.search.query.MogoGeocodeQuery; -import com.mogo.map.search.query.MogoRegeocodeQuery; +import com.mogo.map.impl.amap.search.GeocodeSearchClient; +import com.mogo.map.search.geo.IMogoGeoSearch; +import com.mogo.map.search.geo.IMogoGeoSearchListener; +import com.mogo.map.search.geo.MogoGeocodeAddress; +import com.mogo.map.search.geo.MogoRegeocodeAddress; +import com.mogo.map.search.geo.query.MogoGeocodeQuery; +import com.mogo.map.search.geo.query.MogoRegeocodeQuery; import java.util.List; @@ -59,4 +63,12 @@ public class MogoGeoSearch implements IMogoGeoSearch { mDelegate.getFromLocationNameAsyn( query ); } } + + @Override + public void destroy() { + if ( mDelegate != null ) { + mDelegate.destroy(); + } + mDelegate = null; + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoInputtipsSearch.java b/libraries/mogo-map/src/main/java/com/mogo/map/MogoInputtipsSearch.java similarity index 73% rename from libraries/mogo-map/src/main/java/com/mogo/map/search/MogoInputtipsSearch.java rename to libraries/mogo-map/src/main/java/com/mogo/map/MogoInputtipsSearch.java index 483889b905..5c16622307 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/search/MogoInputtipsSearch.java +++ b/libraries/mogo-map/src/main/java/com/mogo/map/MogoInputtipsSearch.java @@ -1,12 +1,11 @@ -package com.mogo.map.search; +package com.mogo.map; import android.content.Context; -import com.mogo.map.amap.search.InputtipsSearch; -import com.mogo.map.exception.MogoMapException; -import com.mogo.map.search.query.MogoInputtipsQuery; - -import java.util.List; +import com.mogo.map.impl.amap.search.InputtipsSearch; +import com.mogo.map.search.inputtips.IMogoInputtipsListener; +import com.mogo.map.search.inputtips.IMogoInputtipsSearch; +import com.mogo.map.search.inputtips.query.MogoInputtipsQuery; /** * @author congtaowang @@ -44,10 +43,10 @@ public class MogoInputtipsSearch implements IMogoInputtipsSearch { } @Override - public List< MogoTip > requestInputtips() throws MogoMapException { + public void destroy() { if ( mDelegate != null ) { - return mDelegate.requestInputtips(); + mDelegate.destroy(); } - return null; + mDelegate = null; } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/location/MogoLocationClient.java b/libraries/mogo-map/src/main/java/com/mogo/map/MogoLocationClient.java similarity index 70% rename from libraries/mogo-map/src/main/java/com/mogo/map/location/MogoLocationClient.java rename to libraries/mogo-map/src/main/java/com/mogo/map/MogoLocationClient.java index 181444ada4..1ea53c59c2 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/location/MogoLocationClient.java +++ b/libraries/mogo-map/src/main/java/com/mogo/map/MogoLocationClient.java @@ -1,8 +1,11 @@ -package com.mogo.map.location; +package com.mogo.map; import android.content.Context; -import com.mogo.map.amap.location.LocationClient; +import com.mogo.map.impl.amap.location.ALocationClient; +import com.mogo.map.location.IMogoLocationClient; +import com.mogo.map.location.IMogoLocationListener; +import com.mogo.map.location.MogoLocation; /** * @author congtaowang @@ -13,8 +16,8 @@ public class MogoLocationClient implements IMogoLocationClient { private static volatile MogoLocationClient sInstance; - private MogoLocationClient( Context context ) { - mDelegate = LocationClient.getInstance( context ); + public MogoLocationClient( Context context ) { + mDelegate = new ALocationClient( context ); } public static MogoLocationClient getInstance( Context context ) { @@ -52,14 +55,14 @@ public class MogoLocationClient implements IMogoLocationClient { } @Override - public void addLocationListener( ILocationListener listener ) { + public void addLocationListener( IMogoLocationListener listener ) { if ( mDelegate != null ) { mDelegate.addLocationListener( listener ); } } @Override - public void removeLocationListener( ILocationListener listener ) { + public void removeLocationListener( IMogoLocationListener listener ) { if ( mDelegate != null ) { mDelegate.removeLocationListener( listener ); } @@ -72,4 +75,11 @@ public class MogoLocationClient implements IMogoLocationClient { } return null; } + + @Override + public void destroy() { + if ( mDelegate != null ) { + mDelegate.destroy(); + } + } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/MogoMapUIController.java b/libraries/mogo-map/src/main/java/com/mogo/map/MogoMapUIController.java new file mode 100644 index 0000000000..f4642f2440 --- /dev/null +++ b/libraries/mogo-map/src/main/java/com/mogo/map/MogoMapUIController.java @@ -0,0 +1,272 @@ +package com.mogo.map; + +import android.graphics.Point; +import android.graphics.Rect; +import android.location.Location; +import android.view.View; +import android.view.animation.Interpolator; + +import com.mogo.map.impl.amap.uicontroller.AMapUIController; +import com.mogo.map.marker.IMogoMarker; +import com.mogo.map.uicontroller.CarCursorOption; +import com.mogo.map.uicontroller.EnumMapUI; +import com.mogo.map.uicontroller.IMogoMapUIController; +import com.mogo.map.uicontroller.MapCameraPosition; +import com.mogo.map.uicontroller.MapControlResult; + +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-26 + *

+ * 描述 + */ +public class MogoMapUIController implements IMogoMapUIController { + + private IMogoMapUIController mDelegate; + + private static volatile MogoMapUIController sInstance; + + private MogoMapUIController() { + mDelegate = AMapUIController.getInstance(); + } + + public static MogoMapUIController getInstance() { + if (sInstance == null) { + synchronized (MogoMapUIController.class) { + if (sInstance == null) { + sInstance = new MogoMapUIController(); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + @Override + public void setTrafficEnabled(boolean visible) { + if (mDelegate != null) { + mDelegate.setTrafficEnabled(visible); + } + } + + @Override + public MapControlResult changeZoom( boolean zoom) { + if (mDelegate != null) { + return mDelegate.changeZoom(zoom); + } + return MapControlResult.ERROR; + } + + @Override + public MapControlResult changeZoom(float zoom) { + if (mDelegate != null) { + return mDelegate.changeZoom(zoom); + } + return MapControlResult.ERROR; + } + + @Override + public void changeMapMode(EnumMapUI mode) { + if (mDelegate != null) { + mDelegate.changeMapMode(mode); + } + } + + + @Override + public void moveToCenter(MogoLatLng latLng, boolean animate) { + if (mDelegate != null) { + mDelegate.moveToCenter(latLng, animate); + } + } + + @Override + public void showMyLocation(boolean visible) { + if (mDelegate != null) { + mDelegate.showMyLocation(visible); + } + } + + @Override + public void showMyLocation( View view ) { + if ( mDelegate != null ) { + mDelegate.showMyLocation( view ); + } + } + + @Override + public void recoverLockMode() { + if (mDelegate != null) { + mDelegate.recoverLockMode(); + } + } + + @Override + public void loseLockMode() { + if ( mDelegate != null ) { + mDelegate.loseLockMode(); + } + } + + @Override + public void setLockZoom(int var1) { + if (mDelegate != null) { + mDelegate.setLockZoom(var1); + } + } + + @Override + public void displayOverview( Rect bounds ) { + if (mDelegate != null) { + mDelegate.displayOverview(bounds); + } + } + + @Override + public float getScalePerPixel() { + if (mDelegate != null) { + return mDelegate.getScalePerPixel(); + } + 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; + } + + @Override public MogoLatLng getWindowCenterLocation() { + if (mDelegate != null) { + return mDelegate.getWindowCenterLocation(); + } + return null; + } + + @Override + public void setPointToCenter(double mapCenterX, double mapCenterY) { + if (mDelegate != null) { + mDelegate.setPointToCenter(mapCenterX, mapCenterY); + } + } + + @Override + public Point getLocationPointInScreen( MogoLatLng latLng ) { + if (mDelegate != null) { + return mDelegate.getLocationPointInScreen(latLng); + } + return null; + } + + @Override + public MogoLatLng getLocationMogoLatLngInScreen(Point point) { + if (mDelegate != null) { + return mDelegate.getLocationMogoLatLngInScreen(point); + } + return null; + } + + @Override + public void startJumpAnimation( IMogoMarker marker, float high, Interpolator interpolator, long duration ) { + if ( mDelegate != null ) { + mDelegate.startJumpAnimation( marker, high, interpolator, duration ); + } + } + + @Override + public void setRenderFps( int fps ) { + if ( mDelegate != null ) { + mDelegate.setRenderFps( fps ); + } + } + + @Override + public void showBounds(String tag, MogoLatLng carPosition, List< MogoLatLng > lonLats, Rect bound, boolean lockCarPosition ) { + if ( mDelegate != null ) { + mDelegate.showBounds( tag, carPosition, lonLats, bound, lockCarPosition ); + } + } + + @Override + public void forceRender() { + if ( mDelegate != null ) { + mDelegate.forceRender(); + } + } + + @Override + public float calculateLineDistance( MogoLatLng p1, MogoLatLng p2 ) throws Exception { + if ( mDelegate != null ) { + return mDelegate.calculateLineDistance( p1, p2 ); + } + return 0; + } + + @Override + public EnumMapUI getCurrentUiMode() { + if ( mDelegate != null ) { + return mDelegate.getCurrentUiMode(); + } + return null; + } + + @Override + public void changeMyLocation( Location location ) { + if ( mDelegate != null ) { + mDelegate.changeMyLocation( location ); + } + } + + @Override + public boolean isCarLocked() { + if ( mDelegate != null ) { + return mDelegate.isCarLocked(); + } + return false; + } + + @Override + public void setCarCursorOption( CarCursorOption option ) { + if ( mDelegate != null ) { + mDelegate.setCarCursorOption( option ); + } + } + + @Override + public MapCameraPosition getMapCameraPosition() { + if ( mDelegate != null ) { + return mDelegate.getMapCameraPosition(); + } + return null; + } + + @Override + public void changeBearing( float bearing ) { + if ( mDelegate != null ) { + mDelegate.changeBearing( bearing ); + } + } +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/MogoMapView.java b/libraries/mogo-map/src/main/java/com/mogo/map/MogoMapView.java index 342d9d2a83..20c21725d2 100644 --- a/libraries/mogo-map/src/main/java/com/mogo/map/MogoMapView.java +++ b/libraries/mogo-map/src/main/java/com/mogo/map/MogoMapView.java @@ -1,12 +1,13 @@ package com.mogo.map; import android.content.Context; +import android.os.Bundle; import android.util.AttributeSet; import androidx.annotation.Nullable; -import com.amap.api.navi.AMapNaviView; -import com.mogo.map.amap.AMapNaviViewWrapper; +import com.mogo.map.impl.amap.AMapBaseMapView; +import com.mogo.utils.logger.Logger; /** * @author congtaowang @@ -14,8 +15,9 @@ import com.mogo.map.amap.AMapNaviViewWrapper; *

* 地图实例 */ -public class MogoMapView extends MogoBaseMapView { +public class MogoMapView extends AMapBaseMapView implements ILifeCycle { + private static final String TAG = "MogoMapView"; public MogoMapView( Context context ) { super( context ); } @@ -29,7 +31,49 @@ public class MogoMapView extends MogoBaseMapView { } @Override - protected IMogoMapView createMapView( Context context ) { - return new AMapNaviViewWrapper( new AMapNaviView( context ) ); + public IMogoMap getMap() { + return super.getMap(); + } + + @Override + public void onCreate( Bundle bundle ) { + super.onCreate( bundle ); + Logger.d(TAG,"onCreate"); + } + + @Override + public void onResume() { + super.onResume(); + Logger.d(TAG,"onResume"); + + } + + @Override + public void onPause() { + super.onPause(); + Logger.d(TAG,"onPause"); + + } + + @Override + public void onDestroy() { + super.onDestroy(); + Logger.d(TAG,"onDestroy"); + + } + + @Override + public void onSaveInstanceState( Bundle outState ) { + super.onSaveInstanceState( outState ); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + } + + @Override + public IMogoMapView getMapView() { + return super.getMapView(); } } diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/MogoMarkerManager.java b/libraries/mogo-map/src/main/java/com/mogo/map/MogoMarkerManager.java new file mode 100644 index 0000000000..33d7bfff49 --- /dev/null +++ b/libraries/mogo-map/src/main/java/com/mogo/map/MogoMarkerManager.java @@ -0,0 +1,108 @@ +package com.mogo.map; + +import android.content.Context; +import android.util.Log; + +import com.mogo.map.impl.amap.overlay.RouteOverlayHelper; +import com.mogo.map.marker.IMogoMarker; +import com.mogo.map.marker.IMogoMarkerManager; +import com.mogo.map.marker.MogoMarkerOptions; +import com.mogo.map.marker.MogoMarkersHandler; +import com.mogo.utils.logger.Logger; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author congtaowang + * @since 2019-12-20 + *

+ * marker 管理实现 + */ +public class MogoMarkerManager implements IMogoMarkerManager { + + private static final String TAG = "MogoMarkerManager"; + + private static volatile MogoMarkerManager sInstance; + private Context mApplicationContext; + + private MogoMarkerManager( Context context ) { + if ( context != null ) { + mApplicationContext = context.getApplicationContext(); + } + } + + public static MogoMarkerManager getInstance( Context context ) { + if ( sInstance == null ) { + synchronized ( MogoMarkerManager.class ) { + if ( sInstance == null ) { + sInstance = new MogoMarkerManager( context ); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + @Override + public IMogoMarker addMarker( String tag, MogoMarkerOptions options ) { + try { + return MogoMap.getInstance().getMogoMap().addMarker( tag, options ); + } catch ( Exception e ) { + Logger.e( TAG, Log.getStackTraceString( e ) ); + return null; + } + } + + @Override + public List< IMogoMarker > addMarkers( String tag, ArrayList< MogoMarkerOptions > options, boolean moveToCenter ) { + try { + return MogoMap.getInstance().getMogoMap().addMarkers( tag, options, moveToCenter ); + } catch ( Exception e ) { + return null; + } + } + + + @Override + public void removeMarkers( String tag ) { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + MogoMarkersHandler.getInstance().remove( tag ); + } + + @Override + public void removeMarkers() { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + MogoMarkersHandler.getInstance().removeAll(); + } + + @Override + public List< IMogoMarker > getMarkers( String tag ) { + return MogoMarkersHandler.getInstance().getMarkers( tag ); + } + + @Override + public Map< String, List< IMogoMarker > > getAllMarkers() { + return MogoMarkersHandler.getInstance().getAllMarkers(); + } + + @Override + public void removeMarkersExcept( String tag ) { + Logger.d( TAG, Log.getStackTraceString( new Throwable() ) ); + MogoMarkersHandler.getInstance().deleteAllExcept( tag ); + } + + @Override + public void addRouteWay( Context context, MogoLatLng startPoint, MogoLatLng endPoint, List< MogoLatLng > wayPoints ) { + RouteOverlayHelper.getInstance().addRouteWay( context, startPoint, endPoint, wayPoints ); + } + + @Override + public void removeRouteWayOverlay() { + RouteOverlayHelper.getInstance().removeAll(); + } +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/MogoNavi.java b/libraries/mogo-map/src/main/java/com/mogo/map/MogoNavi.java new file mode 100644 index 0000000000..cd43c4147c --- /dev/null +++ b/libraries/mogo-map/src/main/java/com/mogo/map/MogoNavi.java @@ -0,0 +1,245 @@ +package com.mogo.map; + +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.Rect; +import android.location.Location; + +import com.mogo.map.impl.amap.navi.NaviClient; +import com.mogo.map.impl.automap.navi.AutoNaviClient; +import com.mogo.map.navi.IMogoCarLocationChangedListener2; +import com.mogo.map.navi.IMogoNavi; +import com.mogo.map.navi.MogoCalculatePath; +import com.mogo.map.navi.MogoNaviConfig; +import com.mogo.map.navi.OnCalculatePathItemClickInteraction; +import com.mogo.utils.AppUtils; + +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-25 + *

+ * 导航代理 + */ +public class MogoNavi implements IMogoNavi { + + private IMogoNavi mDelegate; + + private static volatile MogoNavi sInstance; + + private MogoNavi( Context context ) { + if ( AppUtils.isAppInstalled( context, "com.autonavi.amapauto" ) ) { + mDelegate = AutoNaviClient.getInstance( context ); + } else { + mDelegate = NaviClient.getInstance( context ); + } + } + + public static MogoNavi getInstance( Context context ) { + if ( sInstance == null ) { + synchronized ( MogoNavi.class ) { + if ( sInstance == null ) { + sInstance = new MogoNavi( context ); + } + } + } + return sInstance; + } + + public synchronized void release() { + sInstance = null; + } + + @Override + public void naviTo( MogoLatLng endPoint ) { + if ( mDelegate != null ) { + mDelegate.naviTo( endPoint ); + } + } + + @Override + public void naviTo( MogoLatLng endPoint, MogoNaviConfig config ) { + if ( mDelegate != null ) { + mDelegate.naviTo( endPoint, config ); + } + } + + @Override + public void naviTo( MogoLatLng endPoint, List< MogoLatLng > wayPoints ) { + if ( mDelegate != null ) { + mDelegate.naviTo( endPoint, wayPoints ); + } + } + + @Override + public void naviTo( MogoLatLng endPoint, List< MogoLatLng > wayPoints, MogoNaviConfig config ) { + if ( mDelegate != null ) { + mDelegate.naviTo( endPoint, wayPoints, config ); + } + } + + @Override + public void reCalculateRoute( MogoNaviConfig config ) { + if ( mDelegate != null ) { + mDelegate.reCalculateRoute( config ); + } + } + + @Override + public void stopNavi() { + if ( mDelegate != null ) { + mDelegate.stopNavi(); + } + } + + @Override + public void startNavi( boolean isRealNavi ) { + if ( mDelegate != null ) { + mDelegate.startNavi( isRealNavi ); + } + } + + @Override + public boolean isNaviing() { + if ( mDelegate != null ) { + return mDelegate.isNaviing(); + } + return false; + } + + @Override + public List< MogoCalculatePath > getCalculatedStrategies() { + if ( mDelegate != null ) { + return mDelegate.getCalculatedStrategies(); + } + return null; + } + + @Override + public List< MogoLatLng > getCalculatedPathPos() { + if ( mDelegate != null ) { + return mDelegate.getCalculatedPathPos(); + } + return null; + } + + @Override + public OnCalculatePathItemClickInteraction getItemClickInteraction() { + if ( mDelegate != null ) { + return mDelegate.getItemClickInteraction(); + } + return null; + } + + @Override + public void setLineClickInteraction( OnCalculatePathItemClickInteraction itemClickInteraction ) { + if ( mDelegate != null ) { + mDelegate.setLineClickInteraction( itemClickInteraction ); + } + } + + @Override + public void clearCalculatePaths() { + if ( mDelegate != null ) { + mDelegate.clearCalculatePaths(); + } + } + + @Override + public void setCalculatePathDisplayBounds( Rect bounds ) { + if ( mDelegate != null ) { + mDelegate.setCalculatePathDisplayBounds( bounds ); + } + } + + @Override + public MogoNaviConfig getNaviConfig() { + if ( mDelegate != null ) { + return mDelegate.getNaviConfig(); + } + return null; + } + + @Override + public boolean setBroadcastMode( int mode ) { + if ( mDelegate != null ) { + return mDelegate.setBroadcastMode( mode ); + } + return false; + } + + @Override + public List< MogoLatLng > getNaviPathCoordinates() { + if ( mDelegate != null ) { + return mDelegate.getNaviPathCoordinates(); + } + return null; + } + + @Override + public MogoLatLng getCarLocation() { + if ( mDelegate != null ) { + return mDelegate.getCarLocation(); + } + return null; + } + + @Override + public Location getCarLocation2() { + if ( mDelegate != null ) { + return mDelegate.getCarLocation2(); + } + return null; + } + + @Override + public void registerCarLocationChangedListener( IMogoCarLocationChangedListener2 listener ) { + if ( mDelegate != null ) { + mDelegate.registerCarLocationChangedListener( listener ); + } + } + + @Override + public void startAimlessMode() { + if ( mDelegate != null ) { + mDelegate.startAimlessMode(); + } + } + + @Override + public void stopAimlessMode() { + if ( mDelegate != null ) { + mDelegate.stopAimlessMode(); + } + } + + @Override + public void setAimlessModeStatus( boolean open ) { + if ( mDelegate != null ) { + mDelegate.setAimlessModeStatus( open ); + } + } + + @Override + public void displayOverview( Rect bounds ) { + if ( mDelegate != null ) { + mDelegate.displayOverview( bounds ); + } + } + + @Override + public void setUseExtraGPSData( boolean use ) { + if ( mDelegate != null ) { + mDelegate.setUseExtraGPSData( use ); + } + } + + @Override + public void setExtraGPSData( double lon, double lat, float speed, float accuracy, float bearing, long timestamp ) { + if ( mDelegate != null ) { + mDelegate.setExtraGPSData( lon, lat, speed, accuracy, bearing, timestamp ); + } + } +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/MogoOverlayManager.java b/libraries/mogo-map/src/main/java/com/mogo/map/MogoOverlayManager.java new file mode 100644 index 0000000000..6cde910cf3 --- /dev/null +++ b/libraries/mogo-map/src/main/java/com/mogo/map/MogoOverlayManager.java @@ -0,0 +1,40 @@ +package com.mogo.map; + +import com.mogo.map.overlay.IMogoOverlayManager; +import com.mogo.map.overlay.IMogoPolyline; +import com.mogo.map.overlay.MogoPolylineOptions; + +/** + * @author congtaowang + * @since 2020-03-10 + *

+ * 描述 + */ +public class MogoOverlayManager implements IMogoOverlayManager { + + private MogoOverlayManager() { + // private constructor + } + + private static final class InstanceHolder { + private static final MogoOverlayManager INSTANCE = new MogoOverlayManager(); + } + + public static MogoOverlayManager getInstance() { + return InstanceHolder.INSTANCE; + } + + private Object readResolve() { + // 阻止反序列化,必须实现 Serializable 接口 + return InstanceHolder.INSTANCE; + } + + @Override + public IMogoPolyline addPolyline( MogoPolylineOptions options ) { + try { + return MogoMap.getInstance().getMogoMap().addPolyline( options ); + } catch ( Exception e ) { + return null; + } + } +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/MogoPoiSearch.java b/libraries/mogo-map/src/main/java/com/mogo/map/MogoPoiSearch.java new file mode 100644 index 0000000000..c40e73de9f --- /dev/null +++ b/libraries/mogo-map/src/main/java/com/mogo/map/MogoPoiSearch.java @@ -0,0 +1,86 @@ +package com.mogo.map; + +import android.content.Context; + +import com.mogo.map.exception.MogoMapException; +import com.mogo.map.impl.amap.search.PoiSearchClient; +import com.mogo.map.search.geo.MogoPoiItem; +import com.mogo.map.search.poisearch.IMogoPoiSearch; +import com.mogo.map.search.poisearch.IMogoPoiSearchListener; +import com.mogo.map.search.poisearch.MogoPoiResult; +import com.mogo.map.search.poisearch.MogoSearchBound; +import com.mogo.map.search.poisearch.query.MogoPoiSearchQuery; + +/** + * @author congtaowang + * @since 2019-12-24 + *

+ * 描述 + */ +public class MogoPoiSearch implements IMogoPoiSearch { + + private IMogoPoiSearch mDelegate; + + public MogoPoiSearch( Context context, MogoPoiSearchQuery query ) { + mDelegate = new PoiSearchClient( context, query ); + } + + @Override + public void setPoiSearchListener( IMogoPoiSearchListener listener ) { + if ( mDelegate != null ) { + mDelegate.setPoiSearchListener( listener ); + } + } + + @Override + public void searchPOIAsyn() { + if ( mDelegate != null ) { + mDelegate.searchPOIAsyn(); + } + } + + @Override + public MogoPoiResult searchPOI() throws MogoMapException { + if ( mDelegate != null ) { + return mDelegate.searchPOI(); + } + return null; + } + + @Override + public void setQuery( MogoPoiSearchQuery query ) { + if ( mDelegate != null ) { + mDelegate.setQuery( query ); + } + } + + @Override + public MogoPoiItem searchPOIId( String poiId ) throws MogoMapException { + if ( mDelegate != null ) { + return mDelegate.searchPOIId( poiId ); + } + return null; + } + + @Override + public void searchPOIIdAsyn( String poiId ) { + if ( mDelegate != null ) { + mDelegate.searchPOIIdAsyn( poiId ); + } + } + + @Override + public void setBound( MogoSearchBound bound ) { + if ( mDelegate != null ) { + mDelegate.setBound( bound ); + } + } + + @Override + public void destroy() { + if ( mDelegate != null ) { + mDelegate.destroy(); + } + mDelegate = null; + } +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/MogoRoadSearch.java b/libraries/mogo-map/src/main/java/com/mogo/map/MogoRoadSearch.java new file mode 100644 index 0000000000..cbd86301c0 --- /dev/null +++ b/libraries/mogo-map/src/main/java/com/mogo/map/MogoRoadSearch.java @@ -0,0 +1,37 @@ +package com.mogo.map; + +import android.content.Context; + +import com.mogo.map.impl.amap.search.RoadSearchClient; +import com.mogo.map.search.drive.IMogoRoadSearch; +import com.mogo.map.search.drive.IMogoRoadSearchListener; +import com.mogo.map.search.drive.MogoRoadSearchQuery; + +/** + * @author congtaowang + * @since 2020/6/1 + *

+ * 描述 + */ +public class MogoRoadSearch implements IMogoRoadSearch { + + private RoadSearchClient mDelegate; + + public MogoRoadSearch() { + mDelegate = new RoadSearchClient(); + } + + @Override + public void searchRoadPath( Context context, MogoRoadSearchQuery query ) { + if ( mDelegate != null ) { + mDelegate.searchRoadPath( context, query ); + } + } + + @Override + public void setRoadPathSearchListener( IMogoRoadSearchListener listener ) { + if ( mDelegate != null ) { + mDelegate.setRoadPathSearchListener( listener ); + } + } +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/amap/AMapNaviViewWrapper.java b/libraries/mogo-map/src/main/java/com/mogo/map/amap/AMapNaviViewWrapper.java deleted file mode 100644 index 5dfdcacb11..0000000000 --- a/libraries/mogo-map/src/main/java/com/mogo/map/amap/AMapNaviViewWrapper.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.mogo.map.amap; - -import android.os.Bundle; -import android.view.View; - -import com.amap.api.navi.AMapNaviView; -import com.mogo.map.IMogoMap; -import com.mogo.map.IMogoMapView; - -/** - * @author congtaowang - * @since 2019-12-18 - *

- * 代理高德导航地图 - */ -public class AMapNaviViewWrapper implements IMogoMapView { - - private final AMapNaviView mMapView; - private IMogoMap mIMap; - - public AMapNaviViewWrapper( AMapNaviView mapView ) { - this.mMapView = mapView; - } - - @Override - public View getMapView() { - return mMapView; - } - - @Override - public IMogoMap getMap() { - if ( mMapView != null ) { - if ( mIMap == null ) { - mIMap = new AMapWrapper( mMapView.getMap() ); - } - } - return mIMap; - } - - @Override - public void onCreate( Bundle bundle ) { - if ( mMapView != null ) { - mMapView.onCreate( bundle ); - } - } - - @Override - public void onResume() { - if ( mMapView != null ) { - mMapView.onResume(); - } - } - - @Override - public void onPause() { - if ( mMapView != null ) { - mMapView.onPause(); - } - } - - @Override - public void onDestroy() { - if ( mMapView != null ) { - mMapView.onDestroy(); - } - } - - @Override - public void onSaveInstanceState( Bundle outState ) { - if ( mMapView != null ) { - mMapView.onSaveInstanceState( outState ); - } - } - - @Override - public void onLowMemory() { - } -} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/amap/AMapWrapper.java b/libraries/mogo-map/src/main/java/com/mogo/map/amap/AMapWrapper.java deleted file mode 100644 index 834b8b58e4..0000000000 --- a/libraries/mogo-map/src/main/java/com/mogo/map/amap/AMapWrapper.java +++ /dev/null @@ -1,153 +0,0 @@ -package com.mogo.map.amap; - -import com.amap.api.maps.AMap; -import com.amap.api.maps.model.Marker; -import com.amap.api.maps.model.MarkerOptions; -import com.mogo.map.IMogoMap; -import com.mogo.map.marker.IMogoMarker; -import com.mogo.map.IUiSettings; -import com.mogo.map.marker.MogoMarkerOptions; -import com.mogo.map.amap.marker.AMapMarkerWrapper; -import com.mogo.map.amap.utils.ObjectUtils; - -import java.util.ArrayList; - -/** - * @author congtaowang - * @since 2019-12-18 - *

- * 代理高德AMap - */ -public class AMapWrapper implements IMogoMap { - - private AMap mAMap; - private IUiSettings mUiSettings; - - public AMapWrapper( AMap map ) { - this.mAMap = map; - } - - @Override - public IUiSettings getUiSettings() { - if ( mUiSettings == null ) { - mUiSettings = new AMapUiSettingsWrapper( mAMap.getUiSettings() ); - } - return mUiSettings; - } - - @Override - public IMogoMarker addMarker( MogoMarkerOptions options ) { - if ( mAMap == null ) { - return null; - } - MarkerOptions markerOptions = ObjectUtils.fromMogo( options ); - if ( markerOptions == null ) { - return null; - } - return new AMapMarkerWrapper( mAMap.addMarker( markerOptions ) ); - } - - @Override - public ArrayList< IMogoMarker > addMarkers( ArrayList< MogoMarkerOptions > options, boolean moveToCenter ) { - - if ( mAMap == null ) { - return null; - } - - if ( options == null || options.isEmpty() ) { - return null; - } - - ArrayList< Marker > markers = null; - ArrayList< MarkerOptions > markerOptions = new ArrayList<>(); - ArrayList< IMogoMarker > mogoMarkers = new ArrayList<>(); - - for ( MogoMarkerOptions option : options ) { - if ( option == null ) { - continue; - } - MarkerOptions mo = ObjectUtils.fromMogo( option ); - if ( mo == null ) { - continue; - } - markerOptions.add( mo ); - } - if ( markerOptions.isEmpty() ) { - return null; - } - markers = mAMap.addMarkers( markerOptions, moveToCenter ); - if ( markers == null || markers.isEmpty() ) { - return null; - } - for ( Marker marker : markers ) { - if ( marker == null ) { - continue; - } - mogoMarkers.add( new AMapMarkerWrapper( marker ) ); - } - return mogoMarkers; - } - - @Override - public void clear() { - if ( mAMap != null ) { - mAMap.clear(); - } - } - - @Override - public void clear( boolean isKeepMyLocationOverlay ) { - if ( mAMap != null ) { - mAMap.clear( isKeepMyLocationOverlay ); - } - } - - @Override - public void setPointToCenter( int x, int y ) { - if ( mAMap != null ) { - mAMap.setPointToCenter( x, y ); - } - } - - @Override - public void setTouchPoiEnable( boolean touchPoiEnable ) { - if ( mAMap != null ) { - mAMap.setTouchPoiEnable( touchPoiEnable ); - } - } - - @Override - public void setTrafficEnable( boolean enable ) { - if ( mAMap != null ) { - mAMap.setTrafficEnabled( enable ); - } - } - - @Override - public void showBuildings( boolean enabled ) { - if ( mAMap != null ) { - mAMap.showBuildings( enabled ); - } - } - - @Override - public void showIndoorMap( boolean enable ) { - if ( mAMap != null ) { - mAMap.showIndoorMap( enable ); - } - } - - @Override - public void showMapText( boolean enable ) { - if ( mAMap != null ) { - mAMap.showMapText( enable ); - } - } - - @Override - public void stopAnimation() { - if ( mAMap != null ) { - mAMap.stopAnimation(); - } - } -} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/amap/location/LocationClient.java b/libraries/mogo-map/src/main/java/com/mogo/map/amap/location/LocationClient.java deleted file mode 100644 index d764ec5b82..0000000000 --- a/libraries/mogo-map/src/main/java/com/mogo/map/amap/location/LocationClient.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.mogo.map.amap.location; - -import android.content.Context; - -import com.amap.api.location.AMapLocation; -import com.amap.api.location.AMapLocationClient; -import com.amap.api.location.AMapLocationClientOption; -import com.amap.api.location.AMapLocationListener; -import com.mogo.map.amap.utils.ObjectUtils; -import com.mogo.map.location.ILocationListener; -import com.mogo.map.location.IMogoLocationClient; -import com.mogo.map.location.MogoLocation; -import com.mogo.utils.logger.Logger; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -/** - * @author congtaowang - * @since 2019-12-19 - *

- * 高德定位 - */ -public class LocationClient implements IMogoLocationClient { - - private static final String TAG = "LocationClient"; - - private static volatile LocationClient sInstance; - private static Set< ILocationListener > sListeners = new HashSet<>( 10 ); - private static MogoLocation sLastLocation = new MogoLocation(); - - private LocationClient( Context context ) { - mClient = new AMapLocationClient( context ); - mClient.setLocationListener( new InternalLocationListener() ); - } - - public static LocationClient getInstance( Context context ) { - if ( sInstance == null ) { - synchronized ( LocationClient.class ) { - if ( sInstance == null ) { - sInstance = new LocationClient( context ); - } - } - } - return sInstance; - } - - private AMapLocationClient mClient; - - @Override - public void start() { - start( 2_000L ); - } - - @Override - public void start( long interval ) { - stop(); - AMapLocationClientOption option = new AMapLocationClientOption(); - option.setLocationMode( AMapLocationClientOption.AMapLocationMode.Hight_Accuracy ); - option.setNeedAddress( true ); - option.setInterval( interval ); - if ( mClient != null ) { - mClient.setLocationOption( option ); - } - } - - @Override - public void stop() { - if ( mClient != null ) { - mClient.stopLocation(); - } - } - - @Override - public void addLocationListener( ILocationListener listener ) { - if ( listener != null ) { - synchronized ( sListeners ) { - sListeners.add( listener ); - } - } - } - - @Override - public void removeLocationListener( ILocationListener listener ) { - if ( listener != null ) { - synchronized ( sListeners ) { - sListeners.remove( listener ); - } - } - } - - @Override - public MogoLocation getLastKnowLocation() { - return sLastLocation; - } - - private static class InternalLocationListener implements AMapLocationListener { - @Override - public void onLocationChanged( AMapLocation aMapLocation ) { - if ( aMapLocation == null || - aMapLocation.getLatitude() == 0.0D || - aMapLocation.getLongitude() == 0.0D ) { - return; - } - Logger.d( TAG, aMapLocation.toString() ); - sLastLocation = ObjectUtils.fromAMap( aMapLocation ); - synchronized ( sListeners ) { - Iterator< ILocationListener > listenerIterator = sListeners.iterator(); - while ( listenerIterator.hasNext() ) { - listenerIterator.next().onLocationChanged( sLastLocation.clone() ); - } - } - } - } -} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/amap/marker/AMapMarkerWrapper.java b/libraries/mogo-map/src/main/java/com/mogo/map/amap/marker/AMapMarkerWrapper.java deleted file mode 100644 index b89701ae59..0000000000 --- a/libraries/mogo-map/src/main/java/com/mogo/map/amap/marker/AMapMarkerWrapper.java +++ /dev/null @@ -1,190 +0,0 @@ -package com.mogo.map.amap.marker; - -import android.graphics.Bitmap; - -import com.amap.api.maps.model.BitmapDescriptor; -import com.amap.api.maps.model.BitmapDescriptorFactory; -import com.amap.api.maps.model.LatLng; -import com.amap.api.maps.model.Marker; -import com.amap.api.maps.model.MarkerOptions; -import com.mogo.map.marker.IMogoMarker; -import com.mogo.map.marker.MogoMarkerOptions; -import com.mogo.map.amap.utils.ObjectUtils; - -import java.util.ArrayList; - -/** - * @author congtaowang - * @since 2019-12-18 - *

- * 代理高德marker - */ -public class AMapMarkerWrapper implements IMogoMarker { - - private Marker mMarker; - - public AMapMarkerWrapper( Marker mMarker ) { - this.mMarker = mMarker; - } - - @Override - public void destroy() { - if ( mMarker != null ) { - mMarker.destroy(); - } - } - - @Override - public void remove() { - if ( mMarker != null ) { - mMarker.remove(); - } - } - - @Override - public void hideInfoWindow() { - if ( mMarker != null ) { - mMarker.hideInfoWindow(); - } - } - - @Override - public void setAlpha( float alpha ) { - if ( mMarker != null ) { - mMarker.setAlpha( alpha ); - } - } - - @Override - public void setAnchor( float anchorU, float anchorV ) { - if ( mMarker != null ) { - mMarker.setAnchor( anchorU, anchorV ); - } - } - - @Override - public void setDraggable( boolean paramBoolean ) { - if ( mMarker != null ) { - mMarker.setDraggable( paramBoolean ); - } - } - - @Override - public void setIcon( Bitmap icon ) { - if ( icon == null || icon.isRecycled() ) { - return; - } - if ( mMarker != null ) { - mMarker.setIcon( BitmapDescriptorFactory.fromBitmap( icon ) ); - } - } - - @Override - public void setIcons( ArrayList< Bitmap > icons ) { - if ( icons == null || icons.isEmpty() ) { - return; - } - ArrayList< BitmapDescriptor > descriptors = new ArrayList<>(); - for ( Bitmap icon : icons ) { - if ( icon == null || icon.isRecycled() ) { - continue; - } - descriptors.add( BitmapDescriptorFactory.fromBitmap( icon ) ); - } - if ( descriptors.isEmpty() ) { - return; - } - if ( mMarker != null ) { - mMarker.setIcons( descriptors ); - } - } - - @Override - public void setInfoWindowEnable( boolean enabled ) { - if ( mMarker != null ) { - mMarker.setInfoWindowEnable( enabled ); - } - } - - @Override - public void setMarkerOptions( MogoMarkerOptions opt ) { - - final MarkerOptions options = ObjectUtils.fromMogo( opt ); - if ( options == null ) { - return; - } - if ( mMarker != null ) { - mMarker.setMarkerOptions( options ); - } - } - - @Override - public void setObject( Object object ) { - if ( mMarker != null ) { - mMarker.setObject( object ); - } - } - - @Override - public void setPeriod( int period ) { - if ( mMarker != null ) { - mMarker.setPeriod( period ); - } - } - - @Override - public void setPosition( double lat, double lng ) { - if ( mMarker != null ) { - mMarker.setPosition( new LatLng( lat, lng ) ); - } - } - - @Override - public void setRotateAngle( float rotate ) { - if ( mMarker != null ) { - mMarker.setRotateAngle( rotate ); - } - } - - @Override - public void setSnippet( String snippet ) { - if ( mMarker != null ) { - mMarker.setSnippet( snippet ); - } - } - - @Override - public void setTitle( String title ) { - if ( mMarker != null ) { - mMarker.setTitle( title ); - } - } - - @Override - public void setToTop() { - if ( mMarker != null ) { - mMarker.setToTop(); - } - } - - @Override - public void setVisible( boolean visible ) { - if ( mMarker != null ) { - mMarker.setVisible( visible ); - } - } - - @Override - public void setZIndex( float zIndex ) { - if ( mMarker != null ) { - mMarker.setZIndex( zIndex ); - } - } - - @Override - public void showInfoWindow() { - if ( mMarker != null ) { - mMarker.showInfoWindow(); - } - } -} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/amap/search/InputtipsSearch.java b/libraries/mogo-map/src/main/java/com/mogo/map/amap/search/InputtipsSearch.java deleted file mode 100644 index 9be69939df..0000000000 --- a/libraries/mogo-map/src/main/java/com/mogo/map/amap/search/InputtipsSearch.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.mogo.map.amap.search; - -import android.content.Context; - -import com.amap.api.services.core.AMapException; -import com.amap.api.services.help.Inputtips; -import com.amap.api.services.help.InputtipsQuery; -import com.amap.api.services.help.Tip; -import com.mogo.map.amap.utils.ObjectUtils; -import com.mogo.map.exception.MogoMapException; -import com.mogo.map.search.IMogoInputtipsListener; -import com.mogo.map.search.IMogoInputtipsSearch; -import com.mogo.map.search.MogoTip; -import com.mogo.map.search.query.MogoInputtipsQuery; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author congtaowang - * @since 2019-12-20 - *

- * 高德地图 inputtips搜索实现 - */ -public class InputtipsSearch implements IMogoInputtipsSearch, Inputtips.InputtipsListener { - - private Inputtips mClient; - private InputtipsQuery mQuery; - private IMogoInputtipsListener mListener; - - public InputtipsSearch( Context context, MogoInputtipsQuery query ) { - mQuery = ObjectUtils.fromMogo( query ); - mClient = new Inputtips( context, mQuery ); - mClient.setInputtipsListener( this ); - } - - @Override - public void setQuery( MogoInputtipsQuery query ) { - this.mQuery = ObjectUtils.fromMogo( query ); - } - - @Override - public void setInputtipsListener( IMogoInputtipsListener listener ) { - this.mListener = listener; - } - - @Override - public void requestInputtipsAsyn() { - if ( mClient != null ) { - mClient.requestInputtipsAsyn(); - } - } - - @Override - public List< MogoTip > requestInputtips() throws MogoMapException { - try { - List< Tip > tips = mClient.requestInputtips(); - List< MogoTip > mogoTips = getResult( tips ); - return mogoTips; - } catch ( AMapException e ) { - throw new MogoMapException( e ); - } - } - - @Override - public void onGetInputtips( List< Tip > list, int i ) { - if ( mListener != null ) { - mListener.onGetInputtips( getResult( list ), i ); - } - } - - private List< MogoTip > getResult( List< Tip > tips ) { - List< MogoTip > mogoTips = new ArrayList<>(); - if ( tips != null ) { - for ( Tip tip : tips ) { - MogoTip mogoTip = ObjectUtils.fromAMap( tip ); - if ( mogoTip != null ) { - mogoTips.add( mogoTip ); - } - } - } - return mogoTips; - } -} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/constants/BroadcastMode.java b/libraries/mogo-map/src/main/java/com/mogo/map/constants/BroadcastMode.java new file mode 100644 index 0000000000..ac6c7a1781 --- /dev/null +++ b/libraries/mogo-map/src/main/java/com/mogo/map/constants/BroadcastMode.java @@ -0,0 +1,10 @@ +package com.mogo.map.constants; + +/** + * @author zyz + * 2020-01-14. + */ +public class BroadcastMode { + public static final int CONCISE = 1; + public static final int DETAIL = 2; +} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/marker/IMogoMarker.java b/libraries/mogo-map/src/main/java/com/mogo/map/marker/IMogoMarker.java deleted file mode 100644 index b6ba461919..0000000000 --- a/libraries/mogo-map/src/main/java/com/mogo/map/marker/IMogoMarker.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.mogo.map.marker; - -import android.graphics.Bitmap; - -import java.util.ArrayList; - -/** - * @author congtaowang - * @since 2019-12-18 - *

- * 地图 marker 抽象 - */ -public interface IMogoMarker { - - /** - * 删除当前marker并销毁Marker的图片等资源 - */ - void destroy(); - - /** - * 删除当前marker。 - */ - void remove(); - - /** - * 隐藏Marker覆盖物的信息窗口。 - */ - void hideInfoWindow(); - - /** - * 设置Marker覆盖物的透明度 - * - * @param alpha - */ - void setAlpha( float alpha ); - - /** - * 设置Marker覆盖物的锚点比例。 - * - * @param anchorU - * @param anchorV - */ - void setAnchor( float anchorU, float anchorV ); - - /** - * 设置Marker覆盖物是否允许拖拽。 - * - * @param paramBoolean - */ - void setDraggable( boolean paramBoolean ); - - /** - * 设置 Marker覆盖物的图标 - * - * @param bitmap - */ - void setIcon( Bitmap bitmap ); - - /** - * 设置 Marker 的图标集合,相同图案的 icon 的 marker 最好使用同一个 BitmapDescriptor 对象以节省内存空间。 - * - * @param icons - */ - void setIcons( ArrayList< Bitmap > icons ); - - /** - * 设置Marker覆盖物的InfoWindow是否允许显示,默认为true - * 设置为false之后, 调用Marker.showInfoWindow() 将不会生效 - * - * @param enabled - */ - void setInfoWindowEnable( boolean enabled ); - - /** - * 设置Marker覆盖物的属性选项类 通过markerOption 给marker设置属性 - * - * @param opt - */ - void setMarkerOptions( MogoMarkerOptions opt ); - - void setObject( Object object ); - - /** - * 设置多少帧刷新一次图片资源,Marker动画的间隔时间,值越小动画越快。 - * - * @param period - */ - void setPeriod( int period ); - - void setPosition( double lat, double lng ); - - /** - * 设置Marker覆盖物图片旋转的角度,从正北开始,逆时针计算。 - * - * @param rotate - */ - void setRotateAngle( float rotate ); - - /** - * 设置Marker 覆盖物的文字片段。 - * - * @param snippet - */ - void setSnippet( String snippet ); - - /** - * 设置Marker 覆盖物的标题。 - * - * @param title - */ - void setTitle( String title ); - - /** - * 设置当前marker在最上面。 - */ - void setToTop(); - - /** - * 设置 Marker 覆盖物的可见属性。 - * - * @param visible - */ - void setVisible( boolean visible ); - - /** - * 设置Marker覆盖物的z轴值。 - * - * @param zIndex - */ - void setZIndex( float zIndex ); - - /** - * 显示 Marker 覆盖物的信息窗口。 - */ - void showInfoWindow(); -} diff --git a/libraries/mogo-map/src/main/java/com/mogo/map/marker/MogoMarker.java b/libraries/mogo-map/src/main/java/com/mogo/map/marker/MogoMarker.java deleted file mode 100644 index 978642da00..0000000000 --- a/libraries/mogo-map/src/main/java/com/mogo/map/marker/MogoMarker.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.mogo.map.marker; - -/** - * @author congtaowang - * @since 2019-12-20 - *

- * 描述 - */ -public class MogoMarker { -} diff --git a/main-extensions/mogo-module-main-independent/.gitignore b/main-extensions/mogo-module-main-independent/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/main-extensions/mogo-module-main-independent/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/main-extensions/mogo-module-main-independent/build.gradle b/main-extensions/mogo-module-main-independent/build.gradle new file mode 100644 index 0000000000..7d208f4876 --- /dev/null +++ b/main-extensions/mogo-module-main-independent/build.gradle @@ -0,0 +1,50 @@ +apply plugin: 'com.android.library' + +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") + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + + javaCompileOptions { + annotationProcessorOptions { + arguments = [AROUTER_MODULE_NAME: project.getName()] + } + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + +} + +dependencies { + 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 + if (Boolean.valueOf(RELEASE)) { + api rootProject.ext.dependencies.modulemain + } else { + api project(":modules:mogo-module-main") + } +} + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() diff --git a/main-extensions/mogo-module-main-independent/consumer-rules.pro b/main-extensions/mogo-module-main-independent/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/main-extensions/mogo-module-main-independent/gradle.properties b/main-extensions/mogo-module-main-independent/gradle.properties new file mode 100644 index 0000000000..48aa348f9c --- /dev/null +++ b/main-extensions/mogo-module-main-independent/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.module +POM_ARTIFACT_ID=module-main-independent +VERSION_CODE=1 diff --git a/main-extensions/mogo-module-main-independent/proguard-rules.pro b/main-extensions/mogo-module-main-independent/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/main-extensions/mogo-module-main-independent/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/main-extensions/mogo-module-main-independent/src/androidTest/java/com/zhidao/mogo/module/main/independent/ExampleInstrumentedTest.java b/main-extensions/mogo-module-main-independent/src/androidTest/java/com/zhidao/mogo/module/main/independent/ExampleInstrumentedTest.java new file mode 100644 index 0000000000..0d481e0787 --- /dev/null +++ b/main-extensions/mogo-module-main-independent/src/androidTest/java/com/zhidao/mogo/module/main/independent/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.zhidao.mogo.module.main.independent; + +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 Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.zhidao.mogo.module.main.independent.test", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/main-extensions/mogo-module-main-independent/src/main/AndroidManifest.xml b/main-extensions/mogo-module-main-independent/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..0d4d401316 --- /dev/null +++ b/main-extensions/mogo-module-main-independent/src/main/AndroidManifest.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/main-extensions/mogo-module-main-independent/src/main/java/com/zhidao/mogo/module/main/independent/MainIndependentActivity.java b/main-extensions/mogo-module-main-independent/src/main/java/com/zhidao/mogo/module/main/independent/MainIndependentActivity.java new file mode 100644 index 0000000000..f085d39fdb --- /dev/null +++ b/main-extensions/mogo-module-main-independent/src/main/java/com/zhidao/mogo/module/main/independent/MainIndependentActivity.java @@ -0,0 +1,51 @@ +package com.zhidao.mogo.module.main.independent; + +import android.os.Bundle; +import android.view.View; +import android.widget.FrameLayout; + +import androidx.annotation.Nullable; + +import com.alibaba.android.arouter.launcher.ARouter; +import com.mogo.commons.debug.DebugConfig; +import com.mogo.module.main.MainActivity; +import com.mogo.service.IMogoServiceApis; +import com.mogo.service.MogoServicePaths; + +/** + * 针对独立应用形式,做单独定制 + * + * @author tongchenfei + */ +public class MainIndependentActivity extends MainActivity { + @Override + protected void onCreate( @Nullable Bundle savedInstanceState ) { + super.onCreate( savedInstanceState ); + // 独立app需要在onCreate里面增加处理scheme的情况 + mPresenter.handleSchemeIntent( getIntent() ); + } + + @Override + protected void initViews() { + super.initViews(); + FrameLayout.LayoutParams entranceParams = ( ( FrameLayout.LayoutParams ) mEntrance.getLayoutParams() ); + entranceParams.leftMargin = getResources().getDimensionPixelSize( R.dimen.module_main_entrance_fragment_container_marginLeft ); + mEntrance.setLayoutParams( entranceParams ); + mLeftShadowFrame.setVisibility(View.VISIBLE); + mApps.setVisibility( View.GONE ); + } + + @Override + protected void onResume() { + super.onResume(); + if ( mCoverUpLayout.getVisibility() != View.VISIBLE ) { + mServiceApis.getAdasControllerApi().setUseAlgorithm( true ); + } + } + + @Override + protected void onPause() { + super.onPause(); + mServiceApis.getAdasControllerApi().setUseAlgorithm( false ); + } +} diff --git a/main-extensions/mogo-module-main-independent/src/main/res/values-xhdpi-1920x1000/dimens.xml b/main-extensions/mogo-module-main-independent/src/main/res/values-xhdpi-1920x1000/dimens.xml new file mode 100644 index 0000000000..c436f9daca --- /dev/null +++ b/main-extensions/mogo-module-main-independent/src/main/res/values-xhdpi-1920x1000/dimens.xml @@ -0,0 +1,5 @@ + + + 635px + 366px + \ No newline at end of file diff --git a/main-extensions/mogo-module-main-independent/src/main/res/values/dimens.xml b/main-extensions/mogo-module-main-independent/src/main/res/values/dimens.xml new file mode 100644 index 0000000000..7c6006c413 --- /dev/null +++ b/main-extensions/mogo-module-main-independent/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 350px + 366px + \ No newline at end of file diff --git a/main-extensions/mogo-module-main-independent/src/test/java/com/zhidao/mogo/module/main/independent/ExampleUnitTest.java b/main-extensions/mogo-module-main-independent/src/test/java/com/zhidao/mogo/module/main/independent/ExampleUnitTest.java new file mode 100644 index 0000000000..1d5940b5c0 --- /dev/null +++ b/main-extensions/mogo-module-main-independent/src/test/java/com/zhidao/mogo/module/main/independent/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.zhidao.mogo.module.main.independent; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/main-extensions/mogo-module-main-launcher/.gitignore b/main-extensions/mogo-module-main-launcher/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/main-extensions/mogo-module-main-launcher/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/main-extensions/mogo-module-main-launcher/build.gradle b/main-extensions/mogo-module-main-launcher/build.gradle new file mode 100644 index 0000000000..4b878becc8 --- /dev/null +++ b/main-extensions/mogo-module-main-launcher/build.gradle @@ -0,0 +1,52 @@ +apply plugin: 'com.android.library' + +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") + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + + javaCompileOptions { + annotationProcessorOptions { + arguments = [AROUTER_MODULE_NAME: project.getName()] + } + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + +} + +dependencies { + 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 + if (Boolean.valueOf(RELEASE)) { + api rootProject.ext.dependencies.modulemain + api rootProject.ext.dependencies.moduleapps + } else { + api project(":modules:mogo-module-main") + api project(':modules:mogo-module-apps') + } +} + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() diff --git a/main-extensions/mogo-module-main-launcher/consumer-rules.pro b/main-extensions/mogo-module-main-launcher/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/main-extensions/mogo-module-main-launcher/gradle.properties b/main-extensions/mogo-module-main-launcher/gradle.properties new file mode 100644 index 0000000000..73da301072 --- /dev/null +++ b/main-extensions/mogo-module-main-launcher/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.module +POM_ARTIFACT_ID=module-main-launcher +VERSION_CODE=1 diff --git a/main-extensions/mogo-module-main-launcher/proguard-rules.pro b/main-extensions/mogo-module-main-launcher/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/main-extensions/mogo-module-main-launcher/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/main-extensions/mogo-module-main-launcher/src/androidTest/java/com/zhidao/mogo/module/main/launcher/ExampleInstrumentedTest.java b/main-extensions/mogo-module-main-launcher/src/androidTest/java/com/zhidao/mogo/module/main/launcher/ExampleInstrumentedTest.java new file mode 100644 index 0000000000..6bccfd240a --- /dev/null +++ b/main-extensions/mogo-module-main-launcher/src/androidTest/java/com/zhidao/mogo/module/main/launcher/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.zhidao.mogo.module.main.launcher; + +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 Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.zhidao.mogo.module.main.launcher.test", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/main-extensions/mogo-module-main-launcher/src/main/AndroidManifest.xml b/main-extensions/mogo-module-main-launcher/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..b59a0bf53e --- /dev/null +++ b/main-extensions/mogo-module-main-launcher/src/main/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/main-extensions/mogo-module-main-launcher/src/main/java/com/zhidao/mogo/module/main/launcher/MainLauncherActivity.java b/main-extensions/mogo-module-main-launcher/src/main/java/com/zhidao/mogo/module/main/launcher/MainLauncherActivity.java new file mode 100644 index 0000000000..59f382ce6a --- /dev/null +++ b/main-extensions/mogo-module-main-launcher/src/main/java/com/zhidao/mogo/module/main/launcher/MainLauncherActivity.java @@ -0,0 +1,61 @@ +package com.zhidao.mogo.module.main.launcher; + +import android.os.Bundle; +import android.view.View; + +import androidx.annotation.Nullable; + +import com.mogo.module.back.BackToLauncherConst; +import com.mogo.module.common.MogoModule; +import com.mogo.module.common.MogoModulePaths; +import com.mogo.module.common.utils.CarSeries; +import com.mogo.module.extensions.utils.ExtensionsConfig; +import com.mogo.module.main.MainActivity; +import com.mogo.module.main.cards.MogoModulesManager; +import com.mogo.utils.logger.Logger; + +/** + * 针对作为Launcher的情况,做个性化操作 + * + * @author tongchenfei + */ +public class MainLauncherActivity extends MainActivity { + @Override + protected void onCreate( @Nullable Bundle savedInstanceState ) { + super.onCreate( savedInstanceState ); + ExtensionsConfig.setNeedRequestUserInfo( true ); + } + + @Override + protected void addModule() { + super.addModule(); + MogoModulePaths.addModule( new MogoModule( BackToLauncherConst.MODULE_PATH, BackToLauncherConst.MODULE_NAME ) ); + } + + @Override + protected void loadContainerModules() { + super.loadContainerModules(); + // 显示左边遮罩 + mLeftShadowFrame.setVisibility( View.VISIBLE ); + MogoModulesManager.getInstance().loadAppsListModule( com.mogo.module.main.R.id.module_main_id_apps_fragment_container ); + } + + @Override + protected void initViews() { + super.initViews(); + } + + @Override + protected void hideLayout() { + super.hideLayout(); + mApps.setVisibility( View.GONE ); + mLeftShadowFrame.setVisibility( View.GONE ); + } + + @Override + protected void showLayout() { + super.showLayout(); + mApps.setVisibility( View.VISIBLE ); + mLeftShadowFrame.setVisibility( View.VISIBLE ); + } +} diff --git a/main-extensions/mogo-module-main-launcher/src/test/java/com/zhidao/mogo/module/main/launcher/ExampleUnitTest.java b/main-extensions/mogo-module-main-launcher/src/test/java/com/zhidao/mogo/module/main/launcher/ExampleUnitTest.java new file mode 100644 index 0000000000..2004abd04d --- /dev/null +++ b/main-extensions/mogo-module-main-launcher/src/test/java/com/zhidao/mogo/module/main/launcher/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.zhidao.mogo.module.main.launcher; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/map-upload.sh b/map-upload.sh new file mode 100755 index 0000000000..f80756c24a --- /dev/null +++ b/map-upload.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +./gradlew :libraries:mogo-map-api:clean :libraries:mogo-map-api:uploadArchives +./gradlew :libraries:map-amap:clean :libraries:map-amap:uploadArchives +./gradlew :libraries:mogo-map:clean :libraries:mogo-map:uploadArchives diff --git a/modules/mogo-module-apps/.gitignore b/modules/mogo-module-apps/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/modules/mogo-module-apps/.gitignore @@ -0,0 +1 @@ +/build diff --git a/modules/mogo-module-apps/README.md b/modules/mogo-module-apps/README.md new file mode 100644 index 0000000000..d1169f3461 --- /dev/null +++ b/modules/mogo-module-apps/README.md @@ -0,0 +1 @@ +# 应用列表 + Launcher 模式下的左侧导航按钮 \ No newline at end of file diff --git a/modules/mogo-module-apps/build.gradle b/modules/mogo-module-apps/build.gradle new file mode 100644 index 0000000000..fa04f473f9 --- /dev/null +++ b/modules/mogo-module-apps/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.library' +apply plugin: 'com.alibaba.arouter' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' + +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' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation rootProject.ext.dependencies.androidxappcompat + implementation rootProject.ext.dependencies.androidxconstraintlayout + implementation rootProject.ext.dependencies.arouter + implementation rootProject.ext.dependencies.material + annotationProcessor rootProject.ext.dependencies.aroutercompiler + implementation rootProject.ext.dependencies.androidxrecyclerview + + if (Boolean.valueOf(RELEASE)) { + implementation rootProject.ext.dependencies.mogomap + implementation rootProject.ext.dependencies.mogomapapi + implementation rootProject.ext.dependencies.mogoutils + api rootProject.ext.dependencies.mogocommons + api rootProject.ext.dependencies.mogoserviceapi + implementation rootProject.ext.dependencies.modulecommon + } else { + implementation project(":libraries:mogo-map") + implementation project(":libraries:mogo-map-api") + implementation 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() diff --git a/modules/mogo-module-apps/consumer-rules.pro b/modules/mogo-module-apps/consumer-rules.pro new file mode 100644 index 0000000000..aad1b810ba --- /dev/null +++ b/modules/mogo-module-apps/consumer-rules.pro @@ -0,0 +1,4 @@ +#-----AppModule----- +-keep class com.mogo.module.apps.model.AppEnum +-keep class com.mogo.module.apps.view.**{*;} +-keep class com.mogo.module.apps.AppFilter \ No newline at end of file diff --git a/modules/mogo-module-apps/gradle.properties b/modules/mogo-module-apps/gradle.properties new file mode 100644 index 0000000000..8f81a71358 --- /dev/null +++ b/modules/mogo-module-apps/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.module +POM_ARTIFACT_ID=module-apps +VERSION_CODE=1 diff --git a/modules/mogo-module-apps/proguard-rules.pro b/modules/mogo-module-apps/proguard-rules.pro new file mode 100644 index 0000000000..66c1a6013a --- /dev/null +++ b/modules/mogo-module-apps/proguard-rules.pro @@ -0,0 +1,26 @@ +# 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 mName 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 mName. +#-renamesourcefileattribute SourceFile + +#-----AppModule----- +-keep class com.mogo.module.apps.model.AppEnum +-keep class com.mogo.module.apps.view.** {*;} +-keep class com.mogo.module.apps.AppFilter diff --git a/modules/mogo-module-apps/src/main/AndroidManifest.xml b/modules/mogo-module-apps/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..d6de6be910 --- /dev/null +++ b/modules/mogo-module-apps/src/main/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppFilter.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppFilter.java new file mode 100644 index 0000000000..f0f5cd93cf --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppFilter.java @@ -0,0 +1,20 @@ +package com.mogo.module.apps; + +import android.content.pm.PackageInfo; + +/** + * @author congtaowang + * @since 2020-01-08 + *

+ * app 过滤规则 + */ +public interface AppFilter { + + /** + * 过滤包 + * + * @param packageInfo + * @return true - 过滤 false - 不过滤 + */ + boolean filter( PackageInfo packageInfo ); +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppFilterImpl.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppFilterImpl.java new file mode 100644 index 0000000000..78e4320bbd --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppFilterImpl.java @@ -0,0 +1,66 @@ +package com.mogo.module.apps; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; + +import com.mogo.module.common.utils.CarSeries; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author congtaowang + * @since 2020-01-08 + *

+ * 过滤 app + */ +public class AppFilterImpl implements AppFilter { + + private final Context mContext; + private List< String > mFilterPackages; + + + public AppFilterImpl( Context context ) { + mContext = context; + if ( CarSeries.getSeries() != CarSeries.CAR_SERIES_F80X ) { + final String[] values = context.getResources().getStringArray( R.array.module_apps_array_filter_packages ); + if ( values != null ) { + mFilterPackages = new ArrayList( Arrays.asList( values ) ); + } + } else { + final String[] values = context.getResources().getStringArray( R.array.module_apps_array_filter_packages_f ); + if ( values != null ) { + mFilterPackages = new ArrayList( Arrays.asList( values ) ); + } + } + } + + @Override + public boolean filter( PackageInfo packageInfo ) { +// if ( isSystemApp( packageInfo ) ) { +// return true; +// } + if ( isFilterPackages( packageInfo ) ) { + return true; + } + if ( noLaunchIntent( packageInfo ) ) { + return true; + } + return false; + } + + private boolean isSystemApp( PackageInfo packageInfo ) { + return ( packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM ) != 0; + } + + private boolean isFilterPackages( PackageInfo packageInfo ) { + return mFilterPackages.contains( packageInfo.packageName ); + } + + private boolean noLaunchIntent( PackageInfo packageInfo ) { + return mContext.getPackageManager().getLaunchIntentForPackage( packageInfo.packageName ) == null; + } + +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppNavigatorFragment.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppNavigatorFragment.java new file mode 100644 index 0000000000..ab5af1e04c --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppNavigatorFragment.java @@ -0,0 +1,155 @@ +package com.mogo.module.apps; + +import android.os.Bundle; +import android.text.TextUtils; +import android.view.View; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.mogo.commons.AbsMogoApplication; +import com.mogo.commons.mvp.MvpFragment; +import com.mogo.module.apps.adapter.AppIndicatorAdapter; +import com.mogo.module.apps.anim.AnimWrapper; +import com.mogo.module.apps.applaunch.AppLauncher; +import com.mogo.module.apps.applaunch.BaseAppLauncher; +import com.mogo.module.apps.applaunch.InternalFunctionLauncher; +import com.mogo.module.apps.model.AppEnum; +import com.mogo.module.apps.model.AppInfo; +import com.mogo.module.apps.model.NavigatorApps; +import com.mogo.module.apps.view.OnAiAssistClickListener; +import com.mogo.utils.AppUtils; +import com.mogo.utils.CommonUtils; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author congtaowang + * @since 2020-01-06 + *

+ * 描述 + */ +public class AppNavigatorFragment extends MvpFragment< AppNavigatorView, AppNavigatorPresenter > implements AppNavigatorView { + + private static final String TAG = "AppNavigatorFragment"; + + private RecyclerView mNavigatorAppsList; + private AppIndicatorAdapter mAppIndicatorAdapter; + + private ImageView mAIAssist; + private View mAIAssistContainer; + private AnimWrapper mAnim = new AnimWrapper(); + + private BaseAppLauncher mLauncher; + + @Override + protected int getLayoutId() { + return R.layout.module_apps_fragment_apps_navigator; + } + + @Override + protected void initViews() { + + mLauncher = new InternalFunctionLauncher( getActivity() ); + mLauncher.setNext( new AppLauncher() ); + + mNavigatorAppsList = findViewById( R.id.module_apps_id_apps_list ); + mNavigatorAppsList.setLayoutManager( new LinearLayoutManager( getActivity(), RecyclerView.VERTICAL, false ) ); + mAppIndicatorAdapter = new AppIndicatorAdapter( getContext(), NavigatorApps.getApps() ); + mAppIndicatorAdapter.setOnItemClickedListener( ( data, position ) -> { + mLauncher.launch( getContext(), data ); + trackNavigatorClickEvent( data ); + } ); + mNavigatorAppsList.setAdapter( mAppIndicatorAdapter ); + + mAIAssistContainer = findViewById( R.id.module_apps_id_ai_assist_container ); + mAIAssist = findViewById( R.id.module_apps_id_ai_assist ); + mAnim.initAnim( mAIAssist ); + mAIAssist.setOnClickListener( new OnAiAssistClickListener() ); + mAIAssistContainer.setOnClickListener( view -> { + mAIAssist.performClick(); + } ); + + AppServiceHandler.getApis().getFragmentManagerApi().addMainFragmentStackTransactionListener( size -> { + // 主页 fragment 栈变化的时候,改变动画状态 + if ( size == 0 ) { + mAnim.start(); + } else { + mAnim.stop(); + } + } ); + } + + @Override + public void hideNavigationEntrance() { + mAppIndicatorAdapter.setDatas( NavigatorApps.getAppsWithoutNavigation() ); + } + + @Override + public void showNavigationEntrance() { + mAppIndicatorAdapter.setDatas( NavigatorApps.getApps() ); + } + + @Override + public void onResume() { + super.onResume(); + mAnim.start(); + } + + @Override + public void onPause() { + super.onPause(); + mAnim.stop(); + } + + @NonNull + @Override + protected AppNavigatorPresenter createPresenter() { + return new AppNavigatorPresenter( this ); + } + + @Override + public void onActivityCreated( @Nullable Bundle savedInstanceState ) { + super.onActivityCreated( savedInstanceState ); + } + + @Override + public void openAppsPanel() { + AppsListActivity.start( getActivity() ); + } + + private void trackNavigatorClickEvent( AppInfo app ) { + final Map< String, Object > properties = new HashMap<>(); + String appLabel = AppUtils.getApplicationLabel( getContext(), app.getPackageName() ); + properties.put( "appname", app.getName() ); + if ( !TextUtils.isEmpty( appLabel ) ) { + properties.put( "appname", appLabel ); + } + if ( !TextUtils.equals( "全部应用", app.getName() ) ) { + if ( TextUtils.equals( "com.zhidao.music", app.getPackageName() ) ) { + if ( AppUtils.isAppInstalled( AbsMogoApplication.getApp(), AppEnum.KwMusic.getPkg() ) ) { + properties.put( "appversion", CommonUtils.getVersionName( getContext(), AppEnum.KwMusic.getPkg() ) ); + } else if ( AppUtils.isAppInstalled( AbsMogoApplication.getApp(), AppEnum.QQMusic.getPkg() ) ) { + properties.put( "appversion", CommonUtils.getVersionName( getContext(), AppEnum.QQMusic.getPkg() ) ); + } + } else { + properties.put( "appversion", CommonUtils.getVersionName( getContext(), app.getPackageName() ) ); + } + } else { + properties.put( "appversion", CommonUtils.getVersionName( getContext() ) ); + } + AppServiceHandler.getMogoAnalytics().track( "Launcher_APP_Icon", properties ); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if ( mPresenter != null ) { + mPresenter.onDestroy( getViewLifecycleOwner() ); + } + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppNavigatorPresenter.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppNavigatorPresenter.java new file mode 100644 index 0000000000..7b39a6b5a3 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppNavigatorPresenter.java @@ -0,0 +1,130 @@ +package com.mogo.module.apps; + +import android.content.Intent; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LifecycleOwner; + +import com.mogo.commons.debug.DebugConfig; +import com.mogo.commons.mvp.Presenter; +import com.mogo.commons.voice.AIAssist; +import com.mogo.commons.voice.IMogoVoiceCmdCallBack; +import com.mogo.map.navi.IMogoNaviListener2; +import com.mogo.module.apps.model.AppsModel; +import com.mogo.service.intent.IMogoIntentListener; +import com.mogo.utils.LaunchUtils; +import com.mogo.utils.TipToast; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * @author congtaowang + * @since 2020-01-12 + *

+ * 描述 + */ +public class AppNavigatorPresenter extends Presenter< AppNavigatorView > implements IMogoIntentListener, + IMogoVoiceCmdCallBack, + IMogoNaviListener2 { + + private static final String TAG = "AppNavigatorPresenter"; + + public AppNavigatorPresenter( AppNavigatorView view ) { + super( view ); + } + + @Override + public void onCreate( @NonNull LifecycleOwner owner ) { + super.onCreate( owner ); + AppServiceHandler.getApis().getRegisterCenterApi().registerMogoNaviListener( TAG, this ); + if ( DebugConfig.isLauncher() ) { + // 预加载应用列表,空间换时间 + AppsModel.getInstance( getContext() ).load( null ); + } + } + + @Override + public void onResume( @NonNull LifecycleOwner owner ) { + super.onResume( owner ); + AIAssist.getInstance( getContext() ).registerUnWakeupCommand( AppsConst.CMD_UN_WAKE_OPEN_APP_LIST, AppsConst.CMD_UN_WAKE_WORDS_OPEN_APP_LIST, this ); + AIAssist.getInstance( getContext() ).registerUnWakeupCommand( AppsConst.CMD_UN_WAKE_OPEN_CAR_SETTINGS, AppsConst.CMD_UN_WAKE_WORDS_OPEN_CAR_SETTINGS, this ); + AppServiceHandler.getApis().getIntentManagerApi().registerIntentListener( AppsConst.COMMAND_OPERATION, this ); + } + + @Override + public void onPause( @NonNull LifecycleOwner owner ) { + super.onPause( owner ); + AppServiceHandler.getApis().getIntentManagerApi().unregisterIntentListener( AppsConst.COMMAND_OPERATION, this ); + AIAssist.getInstance( getContext() ).unregisterUnWakeupCommand( AppsConst.CMD_UN_WAKE_OPEN_APP_LIST ); + AIAssist.getInstance( getContext() ).unregisterUnWakeupCommand( AppsConst.CMD_UN_WAKE_OPEN_CAR_SETTINGS ); + } + + @Override + public void onIntentReceived( String intentStr, Intent intent ) { + if ( !AppsConst.COMMAND_OPERATION.equals( intentStr ) ) { + return; + } + try { + JSONObject object = new JSONObject( intent.getStringExtra( "data" ) ); + String app = object.optString( "object" ); + String operation = object.optString( "operation" ); + + if ( !AppsConst.OBJECT_ADAS.equals( app ) ) { + AppServiceHandler.getApis().getAdasControllerApi().closeADAS(); + } + + if ( !DebugConfig.isLauncher() ) { + return; + } + + if ( AppsConst.OBJECT_ALL_APPS.equals( app ) ) { + if ( AppsConst.OPERATION_OPEN.equals( operation ) ) { + mView.openAppsPanel(); + } + } else if ( AppsConst.OBJECT_FAST_SETTINGS.equals( app ) ) { + if ( AppsConst.OPERATION_OPEN.equals( operation ) ) { + try { + LaunchUtils.launchByPkg( getContext(), AppsConst.APP_PKG_CAR_SETTINGS ); + } catch ( Exception e ) { + TipToast.shortTip( R.string.module_apps_str_no_app ); + } + } + } + } catch ( JSONException e ) { + e.printStackTrace(); + } + } + + @Override + public void onCmdSelected( String cmd ) { + switch ( cmd ) { + case AppsConst.CMD_UN_WAKE_OPEN_APP_LIST: + mView.openAppsPanel(); + break; + case AppsConst.CMD_UN_WAKE_OPEN_CAR_SETTINGS: + try { + LaunchUtils.launchByPkg( getContext(), AppsConst.APP_PKG_CAR_SETTINGS ); + } catch ( Exception e ) { + TipToast.shortTip( R.string.module_apps_str_no_app ); + } + break; + } + } + + @Override + public void onDestroy( @NonNull LifecycleOwner owner ) { + super.onDestroy( owner ); + AppServiceHandler.getApis().getIntentManagerApi().unregisterIntentListener( AppsConst.COMMAND_OPERATION, this ); + } + + @Override + public void onStartNavi() { + mView.hideNavigationEntrance(); + } + + @Override + public void onStopNavi() { + mView.showNavigationEntrance(); + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppNavigatorView.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppNavigatorView.java new file mode 100644 index 0000000000..f67673cb2c --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppNavigatorView.java @@ -0,0 +1,22 @@ +package com.mogo.module.apps; + + +import com.mogo.commons.mvp.IView; + +/** + * @author congtaowang + * @since 2020-01-12 + *

+ * 描述 + */ +public interface AppNavigatorView extends IView { + + /** + * 打开全部应用 + */ + void openAppsPanel(); + + void hideNavigationEntrance(); + + void showNavigationEntrance(); +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppServiceHandler.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppServiceHandler.java new file mode 100644 index 0000000000..043d2cd2bf --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppServiceHandler.java @@ -0,0 +1,48 @@ +package com.mogo.module.apps; + +import android.content.Context; + +import com.alibaba.android.arouter.launcher.ARouter; +import com.mogo.commons.AbsMogoApplication; +import com.mogo.service.IMogoServiceApis; +import com.mogo.service.MogoServicePaths; +import com.mogo.service.analytics.IMogoAnalytics; +import com.mogo.service.cardmanager.IMogoCardManager; + +/** + * author : zyz + * e-mail : 1358506549@qq.com + * date : 2020-01-0718:54 + * desc : 持有服务接口实例 + * version: 1.0 + */ +public class AppServiceHandler { + + private static final String TAG = "AppServiceHandler"; + + private static IMogoServiceApis mApis; + private static IMogoCardManager mMogoCardManager; + private static IMogoAnalytics mMogoAnalytics; + + public static void init( final Context context ) { + mApis = ( IMogoServiceApis ) ARouter.getInstance().build( MogoServicePaths.PATH_SERVICE_APIS ).navigation( context ); + mMogoCardManager = mApis.getCardManagerApi(); + mMogoAnalytics = mApis.getAnalyticsApi(); + + } + + public static IMogoCardManager getMogoCardManager() { + return mMogoCardManager; + } + + public static IMogoAnalytics getMogoAnalytics() { + return mMogoAnalytics; + } + + public static IMogoServiceApis getApis() { + if ( mApis == null ) { + mApis = ( IMogoServiceApis ) ARouter.getInstance().build( MogoServicePaths.PATH_SERVICE_APIS ).navigation( AbsMogoApplication.getApp() ); + } + return mApis; + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsAdapter.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsAdapter.java new file mode 100644 index 0000000000..77f41bccd3 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsAdapter.java @@ -0,0 +1,82 @@ +package com.mogo.module.apps; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.mogo.module.apps.model.AppInfo; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author congtaowang + * @since 2019-12-30 + *

+ * 描述 + */ +public class AppsAdapter extends BaseAdapter { + + private List< AppInfo > mAppInfos; + + public AppsAdapter( List< AppInfo > appInfos ) { + this.mAppInfos = new ArrayList<>( appInfos ); + } + + @Override + public int getCount() { + int size = mAppInfos == null ? 0 : mAppInfos.size(); + return size; + } + + @Override + public AppInfo getItem( int position ) { + return mAppInfos.get( position ); + } + + @Override + public long getItemId( int position ) { + return position; + } + + @Override + public View getView( int position, View convertView, ViewGroup parent ) { + AppViewHolder holder = null; + if ( convertView == null ) { + holder = new AppViewHolder( LayoutInflater.from( parent.getContext() ).inflate( R.layout.module_apps_item_app, null ) ); + } else { + holder = ( ( AppViewHolder ) convertView.getTag() ); + } + AppInfo appInfo = getItem( position ); + if ( appInfo.getIconResId() <= 0 ) { + if ( appInfo.getIcon() != null ) { + holder.mIcon.setImageDrawable( appInfo.getIcon() ); + } else { + holder.mIcon.setImageResource( R.drawable.module_apps_ic_default_icon ); + } + } else { + holder.mIcon.setImageResource( appInfo.getIconResId() ); + } + holder.mName.setText( appInfo.getName() ); + return holder.mItemView; + } + + public static class AppViewHolder { + + private View mItemView; + public ImageView mIcon; + public TextView mName; + + public AppViewHolder( @NonNull View itemView ) { + mItemView = itemView; + mIcon = itemView.findViewById( R.id.module_apps_id_app_icon ); + mName = itemView.findViewById( R.id.module_apps_id_app_name ); + mItemView.setTag( this ); + } + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsConst.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsConst.java new file mode 100644 index 0000000000..2c8ca3d7ab --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsConst.java @@ -0,0 +1,41 @@ +package com.mogo.module.apps; + +/** + * @author congtaowang + * @since 2020-01-08 + *

+ * 描述 + */ +public class AppsConst { + + /** + * 打开/关闭全部应用、打开/关闭车辆设置 + */ + public static final String COMMAND_OPERATION = "system.application.operation"; + + /** + * 每页显示多少个app + */ + public static final int TOTAL_SIZE_EACH_PAGE = 12; + + /** + * 车辆设置跳转 + */ + public static final String APP_PKG_CAR_SETTINGS = "com.zhidao.settings"; + + public static final String OBJECT_ALL_APPS = "全部应用"; + public static final String OBJECT_FAST_SETTINGS = "快捷设置"; + public static final String OBJECT_ADAS = "辅助驾驶"; + public static final String OPERATION_OPEN = "打开"; + public static final String OPERATION_CLOSE = "关闭"; + + public static final String CMD_UN_WAKE_OPEN_APP_LIST = "CMD_UN_WAKE_OPEN_APP_LIST"; + public static final String[] CMD_UN_WAKE_WORDS_OPEN_APP_LIST = new String[]{"打开全部应用"}; + + public static final String CMD_UN_WAKE_CLOSE_APP_LIST = "CMD_UN_WAKE_CLOSE_APP_LIST"; + public static final String[] CMD_UN_WAKE_WORDS_CLOSE_APP_LIST = new String[]{"关闭全部应用"}; + + public static final String CMD_UN_WAKE_OPEN_CAR_SETTINGS = "CMD_UN_WAKE_OPEN_CAR_SETTINGS"; + public static final String[] CMD_UN_WAKE_WORDS_OPEN_CAR_SETTINGS = new String[]{"打开快捷设置"}; + +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsFragment.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsFragment.java new file mode 100644 index 0000000000..ed3de2b4a8 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsFragment.java @@ -0,0 +1,150 @@ +package com.mogo.module.apps; + +import android.os.Bundle; +import android.view.View; +import android.view.animation.DecelerateInterpolator; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.viewpager.widget.ViewPager; + +import com.mogo.commons.mvp.MvpFragment; +import com.mogo.module.apps.model.AppInfo; +import com.mogo.module.apps.view.GridViewPagerScroller; +import com.mogo.module.apps.view.PagerSlidingTabStripV2; +import com.mogo.utils.logger.Logger; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; + +/** + * @author congtaowang + * @since 2019-12-30 + *

+ * 描述 + */ +public class AppsFragment extends MvpFragment< AppsView, AppsPresenter > implements AppsView { + + public static final String TAG = "AppsFragment"; + + private ViewPager mAppsPager; + private AppsPagerAdapter mAppsPagerAdapter; + + private View mExit; + + private View mLoadingView; + private PagerSlidingTabStripV2 mIndicator; + + private GridViewPagerScroller mScroller; + + @Override + protected int getLayoutId() { + return R.layout.module_apps_fragment_apps; + } + + @Override + protected void initViews() { + mAppsPager = findViewById( R.id.module_apps_id_apps_pager ); + mExit = findViewById( R.id.module_apps_id_apps_exit ); + mExit.setOnClickListener( view -> { + if ( getActivity() != null ) { + getActivity().finish(); + getActivity().overridePendingTransition( 0, R.anim.module_apps_anim_exit); + } + } ); +// mAppsList = findViewById( R.id.module_apps_id_apps ); +// mAppsList.setLayoutManager( new GridLayoutManager( getContext(), 8 ) ); + mLoadingView = findViewById( R.id.module_apps_id_loading ); + mLoadingView.setVisibility( View.VISIBLE ); + mIndicator = findViewById( R.id.module_apps_id_indicator ); + mIndicator.setOpenPadding( true ); + + try { + Field mField = ViewPager.class.getDeclaredField("mScroller"); + mField.setAccessible(true); + mScroller = new GridViewPagerScroller(getContext(), new DecelerateInterpolator()); + mField.set(mAppsPager, mScroller); + mScroller.setDuration(160); + + Field field = ViewPager.class.getDeclaredField("mTouchSlop"); + field.setAccessible(true); + field.setInt(mAppsPager, 4); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @NonNull + @Override + protected AppsPresenter createPresenter() { + return new AppsPresenter( this ); + } + + @Override + public void onActivityCreated( @Nullable Bundle savedInstanceState ) { + super.onActivityCreated( savedInstanceState ); + } + + @Override + public void renderApps( Map< Integer, List< AppInfo > > appInfos ) { + mAppsPager.setOffscreenPageLimit( appInfos.size() ); + mLoadingView.setVisibility( View.GONE ); + if ( mAppsPagerAdapter == null ) { + mAppsPagerAdapter = new AppsPagerAdapter( appInfos ); + mAppsPager.setAdapter( mAppsPagerAdapter ); + mAppsPagerAdapter.setOnAppClickedListener( ( appInfo, position ) -> { + Logger.i( TAG, "position = %d clicked. name = %s", position, appInfo.getName() ); + mPresenter.launch( appInfo ); + } ); + } else { + mAppsPagerAdapter.setPagedApps( appInfos ); + } + mIndicator.setViewPager( mAppsPager ); + mLoadingView.setVisibility( View.GONE ); + } + + @Override + public void exit() { + if ( mExit != null ) { + mExit.performClick(); + } + } + +// @Override +// public Animation onCreateAnimation( int transit, boolean enter, int nextAnim ) { +// TranslateAnimation animation = null; +// if ( transit == FragmentTransaction.TRANSIT_FRAGMENT_OPEN ) { +// if ( enter ) { +// animation = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, +// Animation.RELATIVE_TO_SELF, 1, Animation.RELATIVE_TO_SELF, 0 ); +// } else { +// animation = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, -1, +// Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0 ); +// } +// } else if ( FragmentTransaction.TRANSIT_FRAGMENT_CLOSE == transit ) { +// if ( enter ) { +// animation = new TranslateAnimation( Animation.RELATIVE_TO_SELF, -1, Animation.RELATIVE_TO_SELF, 0, +// Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0 ); +// } else { +// animation = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1, +// Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0 ); +// } +// } +// if ( animation == null ) { +// animation = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, +// Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1 ); +// } +// animation.setDuration( 300 ); +// return animation; +// } + + @Override + public void onDestroyView() { + super.onDestroyView(); + if ( mPresenter != null ) { + mPresenter.onDestroy( getViewLifecycleOwner() ); + } + mPresenter = null; + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsFragmentProvider.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsFragmentProvider.java new file mode 100644 index 0000000000..1f0dc91f16 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsFragmentProvider.java @@ -0,0 +1,94 @@ +package com.mogo.module.apps; + +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.marker.IMogoMarkerClickListener; +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 + * @since 2019-12-30 + *

+ * 描述 + */ + +@Route( path = MogoModulePaths.PATH_MODULE_APPS ) +public class AppsFragmentProvider implements IMogoModuleProvider { + + private AppNavigatorFragment mAppsFragment; + + @Override + public Fragment createFragment( Context context, Bundle data ) { + mAppsFragment = new AppNavigatorFragment(); + mAppsFragment.setArguments( data ); + return mAppsFragment; + } + + @Override + public View createView( Context context ) { + return null; + } + + @NonNull + @Override + public String getModuleName() { + return MogoModulePaths.PATH_MODULE_APPS; + } + + @Override + public IMogoModuleLifecycle getCardLifecycle() { + return null; + } + + @Override + public IMogoMapListener getMapListener() { + return null; + } + + @Override + public int getType() { + return ModuleType.TYPE_APP_LIST; + } + + @Override + public IMogoNaviListener getNaviListener() { + return null; + } + + @Override + public IMogoLocationListener getLocationListener() { + return null; + } + + @Override + public void init( Context context ) { + AppServiceHandler.init( context ); + } + + @Override + public IMogoMarkerClickListener getMarkerClickListener() { + return null; + } + + @Override + public String getAppPackage() { + return null; + } + + @Override + public String getAppName() { + return null; + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListActivity.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListActivity.java new file mode 100644 index 0000000000..fbaae3255b --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListActivity.java @@ -0,0 +1,140 @@ +package com.mogo.module.apps; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.os.Build; +import android.os.Bundle; +import android.view.View; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.android.material.bottomsheet.BottomSheetBehavior; +import com.mogo.commons.mvp.MvpActivity; +import com.mogo.module.apps.model.AppsModel; +import com.mogo.service.fragmentmanager.FragmentStackTransactionListener; +import com.mogo.service.fragmentmanager.IMogoFragmentManager; + +/** + * @author congtaowang + * @since 2020-02-28 + *

+ * 描述 + */ +public class AppsListActivity extends MvpActivity< AppsListView, AppsListPresenter > implements AppsListView, FragmentStackTransactionListener { + + private static final String TAG = "AppsListActivity"; + + private BottomSheetBehavior mBottomSheetBehavior; + private IMogoFragmentManager mMogoFragmentManager; + + public static void start( Context context ) { + Intent starter = new Intent( context, AppsListActivity.class ); + context.startActivity( starter ); + } + + @Override + protected void onCreate( @Nullable Bundle savedInstanceState ) { + overridePendingTransition( R.anim.module_apps_anim_enter, 0 ); + getWindow().addFlags( WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS ); + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { + getWindow().setStatusBarColor( Color.BLACK ); + } + super.onCreate( savedInstanceState ); + AppServiceHandler.getApis().getStatusManagerApi().setAppListUIShow( TAG, true ); + } + + @Override + protected void onStart() { + super.onStart(); + try { + AppServiceHandler.getApis().getAdasControllerApi().closeADAS(); + } catch ( Exception e ) { + } + } + + @Override + protected void onRestart() { + super.onRestart(); + try { + AppServiceHandler.getApis().getAdasControllerApi().closeADAS(); + } catch ( Exception e ) { + } + } + + @Override + protected int getLayoutId() { + return R.layout.module_apps_activity_list; + } + + @Override + protected void initViews() { + + getSupportFragmentManager().beginTransaction() + .replace( R.id.module_apps_id_container, new AppsFragment() ) + .commitAllowingStateLoss(); + + mBottomSheetBehavior = BottomSheetBehavior.from( findViewById( R.id.module_apps_id_container ) ); + mBottomSheetBehavior.setSkipCollapsed( true ); + mBottomSheetBehavior.setBottomSheetCallback( new BottomSheetBehavior.BottomSheetCallback() { + @Override + public void onStateChanged( @NonNull View bottomSheet, int newState ) { + if ( newState == BottomSheetBehavior.STATE_COLLAPSED ) { + finish(); + } + } + + @Override + public void onSlide( @NonNull View bottomSheet, float slideOffset ) { + + } + } ); + mBottomSheetBehavior.setState( BottomSheetBehavior.STATE_EXPANDED ); + + mMogoFragmentManager = AppServiceHandler.getApis().getFragmentManagerApi(); + mMogoFragmentManager.addMainFragmentStackTransactionListener( this ); + } + + @NonNull + @Override + protected AppsListPresenter createPresenter() { + return new AppsListPresenter( this ); + } + + @Override + public void onTransaction( int size ) { + if ( size == 0 ) { + closeAppsPanel(); + } + } + + @Override + protected void onRestoreInstanceState( Bundle savedInstanceState ) { + super.onRestoreInstanceState( savedInstanceState ); + AppServiceHandler.getApis().getAdasControllerApi().closeADAS(); + } + + @Override + protected void onSaveInstanceState( Bundle outState ) { + super.onSaveInstanceState( outState ); + AppsModel.getInstance( this ).release(); + } + + @Override + public void closeAppsPanel() { + finish(); + overridePendingTransition( R.anim.module_apps_anim_enter, R.anim.module_apps_anim_exit ); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + AppServiceHandler.getApis().getStatusManagerApi().setAppListUIShow( TAG, false ); + mMogoFragmentManager.removeMainFragmentStackTransactionListener( this ); + mMogoFragmentManager = null; + mBottomSheetBehavior = null; + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListChangedLiveData.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListChangedLiveData.java new file mode 100644 index 0000000000..46ff541f23 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListChangedLiveData.java @@ -0,0 +1,43 @@ +package com.mogo.module.apps; + +import androidx.annotation.NonNull; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Observer; + +/** + * @author congtaowang + * @since 2020-01-13 + *

+ * 描述 + */ +public class AppsListChangedLiveData extends MutableLiveData { + + private Observer mObserver; + + private AppsListChangedLiveData(){ + // private constructor + } + + private static final class InstanceHolder{ + private static final AppsListChangedLiveData INSTANCE = new AppsListChangedLiveData(); + } + + public static AppsListChangedLiveData getInstance(){ + return InstanceHolder.INSTANCE; + } + + private Object readResolve(){ + // 阻止反序列化,必须实现 Serializable 接口 + return InstanceHolder.INSTANCE; + } + + @Override + public void observeForever( @NonNull Observer observer ) { + super.observeForever( observer ); + mObserver = observer; + } + + public void release(){ + removeObserver( mObserver ); + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListPresenter.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListPresenter.java new file mode 100644 index 0000000000..caf44c1c72 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListPresenter.java @@ -0,0 +1,95 @@ +package com.mogo.module.apps; + +import android.content.Intent; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LifecycleOwner; + +import com.alibaba.android.arouter.launcher.ARouter; +import com.mogo.commons.mvp.Presenter; +import com.mogo.commons.voice.AIAssist; +import com.mogo.commons.voice.IMogoVoiceCmdCallBack; +import com.mogo.service.MogoServicePaths; +import com.mogo.service.intent.IMogoIntentListener; +import com.mogo.service.intent.IMogoIntentManager; + +import org.json.JSONException; +import org.json.JSONObject; + +/** + * @author congtaowang + * @since 2020-02-28 + *

+ * 描述 + */ +public class AppsListPresenter extends Presenter< AppsListView > implements IMogoIntentListener, IMogoVoiceCmdCallBack { + + private static final String TAG = "AppsListPresenter"; + + private IMogoIntentManager mIntentManager; + + public AppsListPresenter( AppsListView view ) { + super( view ); + } + + @Override + public void onCreate( @NonNull LifecycleOwner owner ) { + super.onCreate( owner ); + mIntentManager = ( IMogoIntentManager ) ARouter.getInstance().build( MogoServicePaths.PATH_INTENT_MANAGER ).navigation( getContext() ); + mIntentManager.registerIntentListener( AppsConst.COMMAND_OPERATION, this ); + AIAssist.getInstance( getContext() ).registerUnWakeupCommand( AppsConst.CMD_UN_WAKE_CLOSE_APP_LIST, AppsConst.CMD_UN_WAKE_WORDS_CLOSE_APP_LIST, this ); + } + + @Override + public void onIntentReceived( String intentStr, Intent intent ) { + if ( AppsConst.COMMAND_OPERATION.equals( intentStr ) ) { + try { + JSONObject object = new JSONObject( intent.getStringExtra( "data" ) ); + String app = object.optString( "object" ); + String operation = object.optString( "operation" ); + if ( AppsConst.OBJECT_ALL_APPS.equals( app ) ) { + if ( AppsConst.OPERATION_CLOSE.equals( operation ) ) { + mView.closeAppsPanel(); + } + } + } catch ( JSONException e ) { + e.printStackTrace(); + } + } + } + + @Override + public void onCmdSelected( String cmd ) { + if ( TextUtils.equals( AppsConst.CMD_UN_WAKE_CLOSE_APP_LIST, cmd ) ) { + mView.closeAppsPanel(); + } + } + + @Override + public void onCmdAction( String speakText ) { + + } + + @Override + public void onCmdCancel( String speakText ) { + + } + + @Override + public void onSpeakEnd( String speakText ) { + + } + + @Override + public void onSpeakSelectTimeOut( String speakText ) { + + } + + @Override + public void onDestroy( @NonNull LifecycleOwner owner ) { + super.onDestroy( owner ); + mIntentManager.unregisterIntentListener( AppsConst.COMMAND_OPERATION, this ); + AIAssist.getInstance( getContext() ).unregisterUnWakeupCommand( AppsConst.CMD_UN_WAKE_CLOSE_APP_LIST ); + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListView.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListView.java new file mode 100644 index 0000000000..d3ec317ed7 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsListView.java @@ -0,0 +1,14 @@ +package com.mogo.module.apps; + +import com.mogo.commons.mvp.IView; + +/** + * @author congtaowang + * @since 2020-02-28 + *

+ * 描述 + */ +public interface AppsListView extends IView { + + void closeAppsPanel(); +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsPagerAdapter.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsPagerAdapter.java new file mode 100644 index 0000000000..472f22a110 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsPagerAdapter.java @@ -0,0 +1,95 @@ +package com.mogo.module.apps; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.GridView; + +import androidx.annotation.NonNull; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.mogo.module.apps.model.AppInfo; +import com.mogo.module.apps.view.PagerIndicator; +import com.mogo.module.apps.view.PagerSlidingTabStripV2; +import com.mogo.utils.ResourcesHelper; + +import java.util.List; +import java.util.Map; + +/** + * @author congtaowang + * @since 2020-01-08 + *

+ * 描述 + */ +public class AppsPagerAdapter extends PagerAdapter implements PagerSlidingTabStripV2.ViewTabProvider { + + private Map< Integer, List< AppInfo > > mPagedApps; + private OnAppClickedListener mOnAppClickedListener; + + public AppsPagerAdapter( Map< Integer, List< AppInfo > > apps ) { + this.mPagedApps = apps; + } + + @Override + public int getCount() { + return mPagedApps == null ? 0 : mPagedApps.size(); + } + + public void setOnAppClickedListener( OnAppClickedListener onAppClickedListener ) { + this.mOnAppClickedListener = onAppClickedListener; + } + + public OnAppClickedListener getOnAppClickedListener() { + return mOnAppClickedListener; + } + + @Override + public boolean isViewFromObject( @NonNull View view, @NonNull Object object ) { + return view == object; + } + + public void setPagedApps( Map< Integer, List< AppInfo > > pagedApps ) { + this.mPagedApps = pagedApps; + notifyDataSetChanged(); + } + + @NonNull + @Override + public Object instantiateItem( @NonNull ViewGroup container, int position ) { + View pager = LayoutInflater.from( container.getContext() ).inflate( R.layout.module_apps_item_app_pager, null ); + GridView page = pager.findViewById( R.id.module_apps_id_apps_page ); + page.setAdapter( new AppsAdapter( mPagedApps.get( position ) ) ); + page.setOnItemClickListener( ( parent, view, appPosition, id ) -> { + if ( getOnAppClickedListener() != null ) { + getOnAppClickedListener().onClick( mPagedApps.get( position ).get( appPosition ), position * AppsConst.TOTAL_SIZE_EACH_PAGE + appPosition ); + } + } ); + container.addView( page ); + return page; + } + + @Override + public void destroyItem( @NonNull ViewGroup container, int position, @NonNull Object object ) { + if ( object instanceof View ) { + container.removeView( ( ( View ) object ) ); + } + } + + @Override + public int getItemPosition( @NonNull Object object ) { + return POSITION_NONE; + } + + public interface OnAppClickedListener { + void onClick( AppInfo appInfo, int position ); + } + + @Override + public View getPageTabView( Context context, int position ) { + return new PagerIndicator( context ); + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsPresenter.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsPresenter.java new file mode 100644 index 0000000000..916b265020 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsPresenter.java @@ -0,0 +1,240 @@ +package com.mogo.module.apps; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LifecycleOwner; + +import com.alibaba.android.arouter.launcher.ARouter; +import com.mogo.commons.mvp.Presenter; +import com.mogo.module.apps.applaunch.AppLaunchFilter; +import com.mogo.module.apps.applaunch.AppLauncher; +import com.mogo.module.apps.applaunch.CardAppLauncher; +import com.mogo.module.apps.applaunch.GuideShowLauncher; +import com.mogo.module.apps.applaunch.InternalFunctionLauncher; +import com.mogo.module.apps.model.AppInfo; +import com.mogo.module.apps.model.AppsModel; +import com.mogo.module.apps.model.UnScannedApps; +import com.mogo.service.IMogoServiceApis; +import com.mogo.service.MogoServicePaths; +import com.mogo.service.analytics.IMogoAnalytics; +import com.mogo.service.cardmanager.IMogoCardManager; +import com.mogo.service.statusmanager.IMogoStatusManager; +import com.mogo.utils.ThreadPoolService; +import com.mogo.utils.UiThreadHandler; +import com.mogo.utils.logger.Logger; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +/** + * @author congtaowang + * @since 2019-12-30 + *

+ * 描述 + */ +public class AppsPresenter extends Presenter< AppsView > { + + private static final String TAG = "AppsPresenter"; + + private IMogoAnalytics mAnalytics; + private AppLaunchFilter mLauncher; + + private IMogoServiceApis mApis; + + private IMogoCardManager mCardManager; + private IMogoStatusManager mMogoStatusManager; + + public AppsPresenter( AppsView view ) { + super( view ); + mApis = ( IMogoServiceApis ) ARouter.getInstance().build( MogoServicePaths.PATH_SERVICE_APIS ).navigation( getContext() ); + mCardManager = mApis.getCardManagerApi(); + InternalFunctionLauncher internalFunctionLauncher = new InternalFunctionLauncher( getContext() ); + CardAppLauncher cardAppLauncher = new CardAppLauncher( this, mCardManager ); + GuideShowLauncher guideShowLauncher = new GuideShowLauncher( mApis.getMapServiceApi().getNavi( getContext() ) ); + internalFunctionLauncher.setNext( cardAppLauncher ); + cardAppLauncher.setNext( guideShowLauncher ); + guideShowLauncher.setNext( new AppLauncher() ); + mLauncher = internalFunctionLauncher; + } + + @Override + public void onCreate( @NonNull LifecycleOwner owner ) { + super.onCreate( owner ); + renderAppsList(); + AppsListChangedLiveData.getInstance().observeForever( bool -> { + if ( mView != null ) { + renderAppsList(); + } + } ); + + mAnalytics = mApis.getAnalyticsApi(); + mMogoStatusManager = mApis.getStatusManagerApi(); + } + + private void renderAppsList() { + ThreadPoolService.execute( () -> { + AppsModel.getInstance( getContext() ).load( appInfoList -> { + + Logger.d( TAG, "apps: %s", appInfoList ); + final Map< Integer, List< AppInfo > > result = addOthersEntrances( appInfoList ); + final Map< Integer, List< AppInfo > > newResult = rePutInOrderAppList( result ); + UiThreadHandler.post( () -> { + if ( mView != null ) { + mView.renderApps( newResult ); + } + } ); + } ); + + } ); + } + + /** + * 新增入口 + * + * @param appInfoMap + * @return + */ + private Map< Integer, List< AppInfo > > addOthersEntrances( Map< Integer, List< AppInfo > > appInfoMap ) { + Map< Integer, List< AppInfo > > result = new HashMap<>(); + + if ( appInfoMap != null && !appInfoMap.isEmpty() ) { + // val deep copy + Set< Integer > keys = appInfoMap.keySet(); + for ( Integer key : keys ) { + List< AppInfo > val = appInfoMap.get( key ); + try { + result.put( key, new ArrayList<>( val ) ); + } catch ( Exception e ) { + result.put( key, new ArrayList<>() ); + } + } + } + + // 手动添加无法识别到的app + List< AppInfo > apps = UnScannedApps.getUnScannedApps(); + if ( apps != null && !apps.isEmpty() ) { + for ( AppInfo app : apps ) { + if ( app == null ) { + continue; + } + Set< Integer > keys = result.keySet(); + boolean addFlag = true; + for ( Integer key : keys ) { + List< AppInfo > val = result.get( key ); + // 无法扫描到蓝牙电话app,这里手动添加 + for ( AppInfo appInfo : val ) { + if ( appInfo == null ) { + continue; + } + if ( appInfo.equals( app ) ) { + addFlag = false; + break; + } + } + if ( !addFlag ) { + break; + } + } + if ( addFlag ) { + growthCapacity( result ); + result.get( result.size() - 1 ).add( app ); + } + } + } + return result; + } + + /** + * 扩容 + * + * @param target + */ + private void growthCapacity( Map< Integer, List< AppInfo > > target ) { + if ( target == null ) { + return; + } + if ( target.isEmpty() ) { + target.put( 0, new ArrayList<>() ); + } else if ( target.get( target.size() - 1 ) == null ) { + target.put( target.size() - 1, new ArrayList<>() ); + } else if ( target.get( target.size() - 1 ).size() == AppsConst.TOTAL_SIZE_EACH_PAGE ) { + target.put( target.size(), new ArrayList<>() ); + } + } + + private Map< Integer, List< AppInfo > > rePutInOrderAppList( Map< Integer, List< AppInfo > > target ) { + if ( target == null || target.isEmpty() ) { + return new HashMap<>(); + } + Map< Integer, List< AppInfo > > result = new HashMap<>(); + synchronized ( target ) { + List< AppInfo > list = new ArrayList<>(); + for ( List< AppInfo > value : target.values() ) { + for ( AppInfo appInfo : value ) { + if ( list.contains( appInfo ) ) { + continue; + } + list.add( appInfo ); + } + } + int page = 0; + int counter = 0; + for ( AppInfo appInfo : list ) { + if ( counter < AppsConst.TOTAL_SIZE_EACH_PAGE ) { + counter++; + } else { + page++; + counter = 0; + } + if ( !result.containsKey( page ) ) { + result.put( page, new ArrayList<>() ); + } + result.get( page ).add( appInfo ); + } + } + return result; + } + + public void launch( AppInfo appInfo ) { + if ( appInfo == null ) { + return; + } + + trackAppClicked( appInfo ); + try { + mLauncher.launch( getContext(), appInfo ); + } catch ( Exception e ) { + + } + } + + + private void trackAppClicked( AppInfo appInfo ) { + if ( appInfo == null ) { + return; + } + Map< String, Object > properties = new HashMap<>(); + properties.put( "appname", appInfo.getName() ); + properties.put( "packagename", appInfo.getPackageName() ); + properties.put( "appversion", appInfo.getVersionName() ); + properties.put( "from", 1 ); + mAnalytics.track( "appenterfront", properties ); + } + + @Override + public void onDestroy( @NonNull LifecycleOwner owner ) { + super.onDestroy( owner ); + AppsListChangedLiveData.getInstance().release(); + mView = null; + mLauncher.destroy(); + } + + public void exit() { + if ( mView != null ) { + mView.exit(); + } + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsView.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsView.java new file mode 100644 index 0000000000..8539b2e7be --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/AppsView.java @@ -0,0 +1,28 @@ +package com.mogo.module.apps; + +import com.mogo.commons.mvp.IView; +import com.mogo.module.apps.model.AppInfo; + +import java.util.List; +import java.util.Map; + +/** + * @author congtaowang + * @since 2019-12-30 + *

+ * 描述 + */ +public interface AppsView extends IView { + + /** + * 显示加载的app列表 + * + * @param appInfos + */ + void renderApps( Map< Integer, List< AppInfo > > appInfos ); + + /** + * 退出列表页面 + */ + void exit(); +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/adapter/AppIndicatorAdapter.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/adapter/AppIndicatorAdapter.java new file mode 100644 index 0000000000..dfd77cce0c --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/adapter/AppIndicatorAdapter.java @@ -0,0 +1,34 @@ +package com.mogo.module.apps.adapter; + +import android.content.Context; +import android.widget.ImageView; + +import com.mogo.module.apps.R; +import com.mogo.module.apps.adapter.base.RecycleBaseAdapter; +import com.mogo.module.apps.adapter.base.RecycleViewHolder; +import com.mogo.module.apps.model.AppInfo; +import com.mogo.module.apps.model.NavigatorApp; + +import java.util.List; + +/** + * @author zyz + * 2020-03-09. + */ +public class AppIndicatorAdapter extends RecycleBaseAdapter< AppInfo > { + + public AppIndicatorAdapter( Context context, List< AppInfo > list ) { + super( context, list, R.layout.module_apps_item_app_indicator ); + } + + @Override + public void onBindViewHolder( RecycleViewHolder holder, AppInfo app, int position ) { + ImageView ivIndicator = holder.getView( R.id.module_apps_id_app_icon ); + ivIndicator.setImageResource( app.getIconResId() ); + holder.itemView.setOnClickListener( view -> { + if ( getOnItemClickedListener() != null ) { + getOnItemClickedListener().onItemClicked( app, position ); + } + } ); + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/adapter/base/RecycleBaseAdapter.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/adapter/base/RecycleBaseAdapter.java new file mode 100644 index 0000000000..d39ca569b9 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/adapter/base/RecycleBaseAdapter.java @@ -0,0 +1,117 @@ +package com.mogo.module.apps.adapter.base; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +/** + *

+ * Title: adapter + *

+ *

+ * Description: + *

+ *

+ * Copyright: Copyright (c) 2015 + *

+ *

+ *

+ */ +public abstract class RecycleBaseAdapter< T > extends + RecyclerView.Adapter< RecycleViewHolder > { + + protected Context context; + protected List< T > list; + private int resourceID; + + protected OnItemClickListener mOnItemClickedListener; + + /** + * @param context + */ + public RecycleBaseAdapter( Context context, List< T > list, int resourceID ) { + super(); + this.context = context; + this.list = list; + this.resourceID = resourceID; + } + + @Override + public RecycleViewHolder onCreateViewHolder( ViewGroup viewGroup, int viewType ) { + View v = LayoutInflater.from( context ).inflate( resourceID, viewGroup, + false ); + + RecycleViewHolder holder = RecycleViewHolder + .get( v ); + + initHolder( holder ); + + return holder; + } + + @Override + public void onBindViewHolder( RecycleViewHolder viewHolder, int position ) { + onBindViewHolder( viewHolder, list.get( position % list.size()), position ); + } + + @Override + public int getItemCount() { + return list == null ? 0 : list.size(); + } + + public abstract void onBindViewHolder( RecycleViewHolder holder, T t, int position ); + + public void initHolder( RecycleViewHolder holder ) { + + } + + public void setDatas( List< T > list ) { + setDatas( list, false ); + } + + public void setDatas( List< T > list, boolean add ) { + if ( add ) { + this.list.addAll( list ); + } else { + this.list = list; + } + notifyDataSetChanged(); + } + + public void clear() { + if ( list != null ) { + list.clear(); + notifyDataSetChanged(); + } + } + + public T getItem( int position ) { + if ( list == null || list.size() == 0 ) { + return null; + } + return list.get( position ); + } + + public List< T > getList() { + return list; + } + + public interface OnItemClickListener< T > { + void onItemClicked( T data, int position ); + } + + public RecycleBaseAdapter< T > setOnItemClickedListener( OnItemClickListener< T > onItemClickedListener ) { + this.mOnItemClickedListener = onItemClickedListener; + return this; + } + + public OnItemClickListener< T > getOnItemClickedListener() { + return mOnItemClickedListener; + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/adapter/base/RecycleViewHolder.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/adapter/base/RecycleViewHolder.java new file mode 100644 index 0000000000..58bbebbfce --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/adapter/base/RecycleViewHolder.java @@ -0,0 +1,138 @@ +package com.mogo.module.apps.adapter.base; + +import android.graphics.Bitmap; +import android.text.SpannableString; +import android.util.SparseArray; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ImageView; +import android.widget.TextView; +import androidx.recyclerview.widget.RecyclerView; + +public class RecycleViewHolder extends RecyclerView.ViewHolder { + + private SparseArray mViews; + + private View mConvertView; + + public RecycleViewHolder(View itemView) { + super(itemView); + this.mConvertView = itemView; + mViews = new SparseArray(); + // TODO Auto-generated constructor stub + } + + public static RecycleViewHolder get(View itemView) { + return new RecycleViewHolder(itemView); + } + + public View getConvertView() { + return mConvertView; + } + + public T getView(int viewId) { + View view = mViews.get(viewId); + if (view == null) { + view = mConvertView.findViewById(viewId); + mViews.put(viewId, view); + } + return (T) view; + } + + /** + * + * @param viewId + * @param text + * @return + */ + public RecycleViewHolder setText(int viewId, String text) { + TextView tv = getView(viewId); + if (tv==null)return this; + tv.setText(text); + return this; + } + + /** + * + * @param viewId + * @param text + * @return + */ + public RecycleViewHolder setText(int viewId, SpannableString text) { + TextView tv = getView(viewId); + tv.setText(text); + return this; + } + + /** + * + * @param viewId + * @param resId + * @return + */ + public RecycleViewHolder setImageResource(int viewId, int resId) { + ImageView view = getView(viewId); + view.setImageResource(resId); + return this; + } + + /** + * + * @param viewId + * @return + */ + public RecycleViewHolder setImageBitmap(int viewId, Bitmap bitmap) { + ImageView view = getView(viewId); + view.setImageBitmap(bitmap); + return this; + } + + + /** + * + * @param viewId + * @param resId + * @return + */ + // public ViewHolder setImageURI(int viewId, String url) { + // ImageView view = getView(viewId); + // // ImageLoader.getInstance.loadImg(view,url); + // return this; + // } + + /** + * + * @param viewId + * @param resId + * @return + */ + public RecycleViewHolder setBackgroundImage(int viewId, int resId) { + View view = getView(viewId); + view.setBackgroundResource(resId); + return this; + } + + /** + * + * @param viewId + * @param resId + * @return + */ + public RecycleViewHolder setTextColor(int viewId, int resId) { + TextView view = getView(viewId); + view.setTextColor(resId); + return this; + } + + /** + * + * @param viewId + * @return + */ + public RecycleViewHolder setOnClickListener(int viewId, + OnClickListener listener) { + getView(viewId).setOnClickListener(listener); + return this; + } + +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/Anim.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/Anim.java new file mode 100644 index 0000000000..e98e07ee8a --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/Anim.java @@ -0,0 +1,14 @@ +package com.mogo.module.apps.anim; + +/** + * @author congtaowang + * @since 2020-02-26 + *

+ * 描述 + */ +public interface Anim { + + void start(); + + void stop(); +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/AnimRes.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/AnimRes.java new file mode 100644 index 0000000000..e579d0658a --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/AnimRes.java @@ -0,0 +1,84 @@ +package com.mogo.module.apps.anim; + + +import com.mogo.module.apps.R; + +/** + * @author congtaowang + * @since 2020-01-09 + *

+ * 描述 + */ +public class AnimRes { + + public static final int sRes[] = { + R.drawable.mogo_tts_icon_00000, + R.drawable.mogo_tts_icon_00001, + R.drawable.mogo_tts_icon_00002, + R.drawable.mogo_tts_icon_00003, + R.drawable.mogo_tts_icon_00004, + R.drawable.mogo_tts_icon_00005, + R.drawable.mogo_tts_icon_00006, + R.drawable.mogo_tts_icon_00007, + R.drawable.mogo_tts_icon_00008, + R.drawable.mogo_tts_icon_00009, + R.drawable.mogo_tts_icon_00010, + R.drawable.mogo_tts_icon_00011, + R.drawable.mogo_tts_icon_00012, + R.drawable.mogo_tts_icon_00013, + R.drawable.mogo_tts_icon_00014, + R.drawable.mogo_tts_icon_00015, + R.drawable.mogo_tts_icon_00016, + R.drawable.mogo_tts_icon_00017, + R.drawable.mogo_tts_icon_00018, + R.drawable.mogo_tts_icon_00019, + R.drawable.mogo_tts_icon_00020, + R.drawable.mogo_tts_icon_00021, + R.drawable.mogo_tts_icon_00022, + R.drawable.mogo_tts_icon_00023, + R.drawable.mogo_tts_icon_00024, + R.drawable.mogo_tts_icon_00025, + R.drawable.mogo_tts_icon_00026, + R.drawable.mogo_tts_icon_00027, + R.drawable.mogo_tts_icon_00028, + R.drawable.mogo_tts_icon_00029, + R.drawable.mogo_tts_icon_00030, + R.drawable.mogo_tts_icon_00031, + R.drawable.mogo_tts_icon_00032, + R.drawable.mogo_tts_icon_00033, + R.drawable.mogo_tts_icon_00034, + R.drawable.mogo_tts_icon_00035, + R.drawable.mogo_tts_icon_00036, + R.drawable.mogo_tts_icon_00037, + R.drawable.mogo_tts_icon_00038, + R.drawable.mogo_tts_icon_00039, + R.drawable.mogo_tts_icon_00040, + R.drawable.mogo_tts_icon_00041, + R.drawable.mogo_tts_icon_00042, + R.drawable.mogo_tts_icon_00043, + R.drawable.mogo_tts_icon_00044, + R.drawable.mogo_tts_icon_00045, + R.drawable.mogo_tts_icon_00046, + R.drawable.mogo_tts_icon_00047, + R.drawable.mogo_tts_icon_00048, + R.drawable.mogo_tts_icon_00049, + R.drawable.mogo_tts_icon_00050, + R.drawable.mogo_tts_icon_00051, + R.drawable.mogo_tts_icon_00052, + R.drawable.mogo_tts_icon_00053, + R.drawable.mogo_tts_icon_00054, + R.drawable.mogo_tts_icon_00055, + R.drawable.mogo_tts_icon_00056, + R.drawable.mogo_tts_icon_00057, + R.drawable.mogo_tts_icon_00058, + R.drawable.mogo_tts_icon_00059, + R.drawable.mogo_tts_icon_00060, + R.drawable.mogo_tts_icon_00061, + R.drawable.mogo_tts_icon_00062, + R.drawable.mogo_tts_icon_00063, + R.drawable.mogo_tts_icon_00064, + R.drawable.mogo_tts_icon_00065, + R.drawable.mogo_tts_icon_00066, + R.drawable.mogo_tts_icon_00067 + }; +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/AnimWrapper.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/AnimWrapper.java new file mode 100644 index 0000000000..bf38719907 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/AnimWrapper.java @@ -0,0 +1,68 @@ +package com.mogo.module.apps.anim; + +import android.graphics.drawable.AnimationDrawable; +import android.widget.ImageView; + +import com.mogo.module.apps.R; +import com.mogo.module.common.utils.CarSeries; +import com.mogo.utils.ThreadPoolService; +import com.mogo.utils.UiThreadHandler; +import com.mogo.utils.logger.Logger; + +/** + * @author congtaowang + * @since 2020-02-26 + *

+ * 描述 + */ +public class AnimWrapper implements Anim { + + private static final String TAG = "AnimWrapper"; + private ImageView mTarget; + private Anim mDelegate; + private boolean mIsStarted = false; + + public AnimWrapper() { + } + + public void initAnim( ImageView target ) { + mTarget = target; + if ( CarSeries.getSeries() == CarSeries.CAR_SERIES_F80X ) { + ThreadPoolService.execute( () -> { + final AnimationDrawable drawable = new AnimationDrawable(); + for ( int i = 0; i < AnimRes.sRes.length; i++ ) { + drawable.addFrame( target.getResources().getDrawable( AnimRes.sRes[i] ), 100 ); + } + UiThreadHandler.post( () -> { + target.setBackground( drawable ); + mDelegate = new OthersAnim( drawable ); + start(); + } ); + } ); + } else { + mTarget.setImageResource( R.drawable.mogo_tts_icon_00000 ); + } + } + + @Override + public synchronized void start() { + if ( mDelegate != null && !mIsStarted ) { + mIsStarted = true; + mDelegate.start(); + Logger.d( TAG, "开启小智动画" ); + } + } + + @Override + public void stop() { + if ( mDelegate != null ) { + mIsStarted = false; + mDelegate.stop(); + Logger.d( TAG, "停止小智动画" ); + } + } + + public void release() { + mDelegate = null; + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/JSurfaceView.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/JSurfaceView.java new file mode 100644 index 0000000000..b70218743b --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/JSurfaceView.java @@ -0,0 +1,183 @@ +package com.mogo.module.apps.anim; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +import com.mogo.utils.logger.Logger; + +import java.lang.ref.WeakReference; +import java.util.HashMap; +import java.util.Map; + +public class JSurfaceView extends SurfaceView implements Runnable, SurfaceHolder.Callback { + + private static final String TAG = "JSurfaceView"; + + private SurfaceHolder mHolder; + + /** + * 动画是否执行中 + */ + private boolean bRunning = false; + /** + * 当前执行的第几帧 + */ + private int mCurrentPos; + /** + * 动画集合 + */ + private int[] mFrames; + + private Thread mThread; + + // 使用 BitmapFactory.Option.inBitmap 属性复用 bitmap 对象 + private Bitmap mContainerBitmap = null; + + // mContainerBitmap 是否生效 + private boolean mContainerBitmapStatus = true; + + // mContainerBitmapStatus 为 false 时,使用该缓存方案 + private Map< Integer, WeakReference< Bitmap > > mBitmapRefMap = new HashMap<>(); + + public JSurfaceView( Context context ) { + super( context ); + init(); + } + + public JSurfaceView( Context context, AttributeSet attrs ) { + super( context, attrs ); + init(); + } + + public JSurfaceView( Context context, AttributeSet attrs, int defStyleAttr ) { + super( context, attrs, defStyleAttr ); + init(); + } + + private void init() { + mHolder = getHolder(); + mHolder.addCallback( this ); + setZOrderOnTop( true ); + mHolder.setFormat( PixelFormat.TRANSLUCENT ); + } + + public void setFrames( int[] frames ) { + mFrames = frames; + } + + public void startAnim() { + if ( bRunning ) { + return; + } + bRunning = true; + mThread = new Thread( this ); + mThread.setName( TAG + "thread" ); + mThread.start(); + } + + public void stop() { + bRunning = false; + try { + mThread.interrupt(); + mThread = null; + } catch ( Exception e ) { + e.printStackTrace(); + } + } + + @Override + public void run() { + while ( bRunning ) { + drawBitmap(); + mCurrentPos++; + try { + Thread.sleep( 100 ); + } catch ( InterruptedException e ) { + e.printStackTrace(); + } + } + } + + + private void drawBitmap() { + //获取画布并锁定 + Canvas canvas = mHolder.lockCanvas(); + if ( canvas == null ) { + return; + } + //绘制透明色 + canvas.drawColor( Color.TRANSPARENT, PorterDuff.Mode.CLEAR ); + + int factPosition = mCurrentPos % mFrames.length; + + if ( mContainerBitmapStatus ) { + if ( mContainerBitmap == null ) { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inMutable = true; + mContainerBitmap = BitmapFactory.decodeResource( getResources(), mFrames[factPosition], options ); + } else { + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inMutable = true; + options.inBitmap = mContainerBitmap; + try { + BitmapFactory.decodeResource( getResources(), mFrames[factPosition], options ); + } catch ( Exception e ) { + Logger.e( TAG, e, "error." ); + mContainerBitmapStatus = false; + mContainerBitmap = null; + } + } + } + if ( !mContainerBitmapStatus ) { + WeakReference< Bitmap > ref = mBitmapRefMap.get( factPosition ); + if ( ref != null && ref.get() != null && !ref.get().isRecycled() ) { + mContainerBitmap = ref.get(); + } else { + mContainerBitmap = BitmapFactory.decodeResource( getResources(), mFrames[factPosition] ); + mBitmapRefMap.put( factPosition, new WeakReference<>( mContainerBitmap ) ); + } + } + + if ( mContainerBitmap == null || mContainerBitmap.isRecycled() ) { + return; + } + + Paint paint = new Paint(); + Rect mSrcRect = new Rect( 0, + 0, + mContainerBitmap.getWidth(), + mContainerBitmap.getHeight() ); // 图片绘制 + Rect mDestRect = new Rect( 0, + 0, + getWidth(), + getHeight() );// 图片绘制位置 + + canvas.drawBitmap( mContainerBitmap, mSrcRect, mDestRect, paint ); + //解锁画布,并展示bitmap到surface + mHolder.unlockCanvasAndPost( canvas ); + } + + @Override + public void surfaceCreated( SurfaceHolder holder ) { + } + + @Override + public void surfaceChanged( SurfaceHolder holder, int format, int width, int height ) { + + } + + @Override + public void surfaceDestroyed( SurfaceHolder holder ) { + + } +} \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/KitkatAnim.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/KitkatAnim.java new file mode 100644 index 0000000000..2f3f864367 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/KitkatAnim.java @@ -0,0 +1,20 @@ +package com.mogo.module.apps.anim; + +/** + * @author congtaowang + * @since 2020-02-26 + *

+ * 描述 + */ +public class KitkatAnim implements Anim{ + + @Override + public void start() { + + } + + @Override + public void stop() { + + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/OthersAnim.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/OthersAnim.java new file mode 100644 index 0000000000..13156b1e7c --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/anim/OthersAnim.java @@ -0,0 +1,32 @@ +package com.mogo.module.apps.anim; + +import android.graphics.drawable.AnimationDrawable; + +/** + * @author congtaowang + * @since 2020-02-26 + *

+ * 描述 + */ +public class OthersAnim implements Anim{ + + private AnimationDrawable mDrawable; + + public OthersAnim( AnimationDrawable drawable ) { + this.mDrawable = drawable; + } + + @Override + public void start() { + if ( mDrawable != null ) { + mDrawable.start(); + } + } + + @Override + public void stop() { + if ( mDrawable != null ) { + mDrawable.stop(); + } + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/AppLaunchFilter.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/AppLaunchFilter.java new file mode 100644 index 0000000000..3bab4c03e6 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/AppLaunchFilter.java @@ -0,0 +1,20 @@ +package com.mogo.module.apps.applaunch; + +import android.content.Context; + +import com.mogo.module.apps.model.AppInfo; + +/** + * @author congtaowang + * @since 2020-02-09 + *

+ * 按指定方式启动指定的app + */ +public interface AppLaunchFilter { + + void launch( Context context, AppInfo appInfo ); + + void launch( Context context, String pkg ); + + void destroy(); +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/AppLauncher.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/AppLauncher.java new file mode 100644 index 0000000000..f148156e82 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/AppLauncher.java @@ -0,0 +1,34 @@ +package com.mogo.module.apps.applaunch; + +import android.content.Context; + +import com.mogo.module.apps.AppServiceHandler; +import com.mogo.module.apps.R; +import com.mogo.module.apps.model.AppInfo; +import com.mogo.utils.LaunchUtils; +import com.mogo.utils.TipToast; +import com.mogo.utils.logger.Logger; + +/** + * @author congtaowang + * @since 2020-02-09 + *

+ * 描述 + */ +public class AppLauncher extends BaseAppLauncher { + + private static final String TAG = "AppLauncher"; + + @Override + public void launch( Context context, AppInfo appInfo ) { + launch( context, appInfo.getPackageName() ); + } + + @Override + public void destroy() { + if ( getNext() != null ) { + getNext().destroy(); + setNext( null ); + } + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/BaseAppLauncher.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/BaseAppLauncher.java new file mode 100644 index 0000000000..2b27fb3566 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/BaseAppLauncher.java @@ -0,0 +1,43 @@ +package com.mogo.module.apps.applaunch; + +import android.content.Context; + +import com.mogo.module.apps.AppServiceHandler; +import com.mogo.module.apps.R; +import com.mogo.utils.LaunchUtils; +import com.mogo.utils.TipToast; +import com.mogo.utils.logger.Logger; + +/** + * @author congtaowang + * @since 2020-02-09 + *

+ * 描述 + */ +public abstract class BaseAppLauncher implements AppLaunchFilter { + + private static final String TAG = "BaseAppLauncher"; + + private AppLaunchFilter mNext; + + public AppLaunchFilter getNext() { + return mNext; + } + + public void setNext( AppLaunchFilter next ) { + this.mNext = next; + } + + @Override + public void launch( Context context, String pkg ) { + try { + if ( LaunchUtils.getLaunchIntentForPackage( context, pkg ) != null ) { + AppServiceHandler.getApis().getAdasControllerApi().closeADAS(); + } + LaunchUtils.launchByPkg( context, pkg ); + } catch ( Exception e ) { + Logger.e( TAG, e, "error." ); + TipToast.shortTip( R.string.module_apps_str_no_app ); + } + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/CardAppLauncher.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/CardAppLauncher.java new file mode 100644 index 0000000000..117dd06cb8 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/CardAppLauncher.java @@ -0,0 +1,52 @@ +package com.mogo.module.apps.applaunch; + +import android.content.Context; + +import com.mogo.module.apps.AppsPresenter; +import com.mogo.module.apps.model.AppInfo; +import com.mogo.service.cardmanager.IMogoCardManager; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author congtaowang + * @since 2020-02-09 + *

+ * 描述 + */ +public class CardAppLauncher extends BaseAppLauncher { + + private static Map< String, String > sCardApps = new HashMap<>(); + + static { + sCardApps.put( "com.zhidao.roadcondition.split", "CARD_TYPE_ROAD_CONDITION" ); + sCardApps.put( "com.zhidao.roadcondition", "CARD_TYPE_ROAD_CONDITION" ); + sCardApps.put( "com.zhidao.imdemo", "CARD_TYPE_CARS_CHATTING" ); + } + + private AppsPresenter mAppsPresenter; + private IMogoCardManager mCardManager; + + public CardAppLauncher( AppsPresenter mAppsPresenter, IMogoCardManager mCardManager ) { + this.mAppsPresenter = mAppsPresenter; + this.mCardManager = mCardManager; + } + + @Override + public void launch( Context context, AppInfo appInfo ) { + if ( getNext() != null ) { + getNext().launch( context, appInfo ); + } + } + + @Override + public void destroy() { + mAppsPresenter = null; + mCardManager = null; + if ( getNext() != null ) { + getNext().destroy(); + setNext( null ); + } + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/GuideShowLauncher.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/GuideShowLauncher.java new file mode 100644 index 0000000000..fea3414ea7 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/GuideShowLauncher.java @@ -0,0 +1,37 @@ +package com.mogo.module.apps.applaunch; + +import android.content.Context; + +import com.mogo.map.navi.IMogoNavi; +import com.mogo.module.apps.model.AppInfo; + +public class GuideShowLauncher extends BaseAppLauncher { + + public static final String TAG = "GuideShowLauncher"; + public static final String APP_INFO_NAME_GUIDE_SHOW = "新手引导"; + + private IMogoNavi mNavi; + + public GuideShowLauncher( IMogoNavi navi ) { + this.mNavi = navi; + } + + @Override + public void launch(Context context, AppInfo appInfo) { + processChain(context, appInfo); + } + + private void processChain(Context context, AppInfo appInfo) { + if (getNext() != null) { + getNext().launch(context, appInfo); + } + } + + @Override + public void destroy() { + if (getNext() != null) { + getNext().destroy(); + setNext(null); + } + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/InternalFunctionLauncher.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/InternalFunctionLauncher.java new file mode 100644 index 0000000000..75af6c4455 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/applaunch/InternalFunctionLauncher.java @@ -0,0 +1,108 @@ +package com.mogo.module.apps.applaunch; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; + +import com.mogo.commons.AbsMogoApplication; +import com.mogo.module.apps.AppServiceHandler; +import com.mogo.module.apps.AppsListActivity; +import com.mogo.module.apps.R; +import com.mogo.module.apps.model.AppEnum; +import com.mogo.module.apps.model.AppInfo; +import com.mogo.module.common.map.CustomNaviInterrupter; +import com.mogo.utils.AppUtils; +import com.mogo.utils.LaunchUtils; +import com.mogo.utils.TipToast; +import com.mogo.utils.logger.Logger; + +/** + * @author congtaowang + * @since 2020-05-14 + *

+ * 处理一些特殊的跳转 + */ +public class InternalFunctionLauncher extends BaseAppLauncher { + + private Context mContext; + + public InternalFunctionLauncher( Context activity ) { + this.mContext = activity; + } + + @Override + public void launch( Context context, AppInfo appInfo ) { + switch ( appInfo.getPackageName() ) { + case "com.autonavi.amapauto": + if ( CustomNaviInterrupter.getInstance().interrupt() ) { + try { + launch( context, AppEnum.AUTO_NAVI.getPkg() ); + } catch ( Exception e ) { + e.printStackTrace(); + } + } else { + AppServiceHandler.getApis().getSearchManagerApi().showSearch(); + } + break; + case "com.mogo.launcher.applist": + AppsListActivity.start( mContext ); + break; + case "com.zhidao.bluetooth": + if ( TextUtils.equals( "蓝牙音乐", appInfo.getName() ) ) { + startActivity( context, appInfo, "com.zhidao.bluetooth.ui.MusicActivity" ); + } else if ( TextUtils.equals( "蓝牙电话", appInfo.getName() ) ) { + startActivity( context, appInfo, "com.zhidao.bluetooth.ui.MainActivity" ); + } + break; + case "com.zhidao.music": + if ( AppUtils.isAppInstalled( AbsMogoApplication.getApp(), AppEnum.KwMusic.getPkg() ) ) { + try { + launch( context, AppEnum.KwMusic.getPkg() ); + } catch ( Exception e ) { + e.printStackTrace(); + } + } else if ( AppUtils.isAppInstalled( AbsMogoApplication.getApp(), AppEnum.QQMusic.getPkg() ) ) { + try { + launch( context, AppEnum.QQMusic.getPkg() ); + } catch ( Exception e ) { + e.printStackTrace(); + } + } else { + TipToast.shortTip( R.string.module_apps_str_no_app ); + } + break; + default: + if ( getNext() != null ) { + getNext().launch( context, appInfo ); + } + } + } + + private void startActivity( Context context, AppInfo target, String page ) { + if ( context == null || target == null ) { + return; + } + if ( TextUtils.isEmpty( page ) ) { + if ( getNext() != null ) { + getNext().launch( context, target ); + return; + } + } + try { + Intent intent = new Intent(); + intent.setComponent( new ComponentName( target.getPackageName(), page ) ); + intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK ); + context.startActivity( intent ); + } catch ( Exception e ) { + TipToast.shortTip( "APP未安装" ); + } + } + + @Override + public void destroy() { + if ( getNext() != null ) { + getNext().destroy(); + } + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppEnum.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppEnum.java new file mode 100644 index 0000000000..f6d9fa7c18 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppEnum.java @@ -0,0 +1,127 @@ +package com.mogo.module.apps.model; + +import com.mogo.module.apps.R; + +/** + * @author congtaowang + * @since 2020-02-12 + *

+ * 定制化的 app 列表 + *

+ *

+ * 自研类:QQ音乐、车聊聊、探路、新鲜事、福利、蘑菇小队、行车记录仪、懒人听书、一键清理、系统升级 + * 第三方:车机微信助手、爱奇艺、喜马拉雅 + * 基础类:均衡器、方控学习、蓝牙、FM、车载设置、AUX + */ +public enum AppEnum { + // 酷我音乐 + KwMusic("酷我音乐", "cn.kuwo.kwmusiccar", R.drawable.ic_kuwo), + // 爱趣听 + WeCarFlow("爱趣听","com.tencent.wecarflow", R.drawable.module_apps_ic_we_car_flow ), + //"QQ音乐", + QQMusic( "QQ音乐", "com.pvetec.musics", R.drawable.module_apps_ic_qq_music ), + + //"车聊聊", + Im( "车聊聊", "com.zhidao.imdemo", R.drawable.module_apps_ic_im ), + + //"探路", +// RoadCondition( "探路", "com.zhidao.roadcondition", R.drawable.module_apps_ic_road_condition ), +// RoadConditionSlit( "探路", "com.zhidao.roadcondition.split", R.drawable.module_apps_ic_road_condition ), + + //"福利", + Welfare( "福利", "com.zhidaohulian.welfare.car", R.drawable.module_apps_ic_welfare ), + + //"蘑菇小队", + Fleet( "蘑菇小队", "com.zhidao.fleet", R.drawable.module_apps_ic_fleet ), + + //"行车记录仪", + CarCorder( "行车记录仪", "com.zhidao.carcorder", R.drawable.module_apps_ic_carcorder ), + + //"懒人听书", + Lrts( "懒人听书", "com.zhidao.lrts", R.drawable.module_apps_ic_lrts ), + + //"一键清理", + CleanMaster( "一键清理", "com.zhidao.cleanmaster", R.drawable.module_apps_ic_clean_master ), + + //"系统升级", + Fota( "系统升级", "com.abupdate.fota_demo_iot", R.drawable.module_apps_ic_fota ), + + //"微信车机助手", + WechatHelper( "微信车机助手", "com.zhidao.wechathelper", R.drawable.module_apps_ic_wechat ), + + //"爱奇艺HD", + Qiyi( "爱奇艺HD", "com.qiyi.video.pad", R.drawable.module_apps_ic_qiyi ), + + //"喜马拉雅", + Ximalaya( "喜马拉雅", "com.ximalaya.ting.android.car", R.drawable.module_apps_ic_ximalaya ), + + //"均衡器", + Equlizer( "均衡器", "com.zhidao.equalizer", R.drawable.module_apps_ic_equlizer ), + Equlizer_NWD( "均衡器", "com.nwd.audioset", R.drawable.module_apps_ic_equlizer ), + + //"方控学习", + SteerProduct( "方控学习", "com.zd.steerproduct", R.drawable.module_apps_ic_stee_product ), + SteerProduct_NWD( "方控学习", "com.nwd.wheel.learning", R.drawable.module_apps_ic_stee_product ), + + //"车载设置", + CarSettings( "车载设置", "com.zhidao.settings", R.drawable.module_apps_ic_car_setting ), + + //"AUX", + AUX( "AUX", "com.nwd.auxin", R.drawable.module_apps_ic_aux ), + + //FM + FM( "FM收音机", "com.nwd.radio", R.drawable.module_apps_ic_fm ), + + // 新鲜事 + FreshThings( "新鲜事", "com.zhidao.fresh.things", R.drawable.module_apps_ic_fresh_things ), + + // 个人中心 + PersonCenter( "个人中心", "com.zhidao.auto.personal", R.drawable.module_apps_ic_personal_center ), + + // 本地视频 + LocalVideo( "本地视频", "com.zhidao.video", R.drawable.module_apps_ic_local_video ), + LocalVideo_NWD( "本地视频", "com.nwd.android.video.ui", R.drawable.module_apps_ic_local_video ), + + // 车辆信息 + CanBus( "车辆信息", "com.nwd.can.setting", R.drawable.module_apps_ic_canbus ), + + // 蓝牙电话 + BT_PHONE_NWD( "蓝牙电话", "com.nwd.android.phone", R.drawable.module_apps_ic_bt_phone ), + BT_PHONE( "蓝牙电话", "com.zhidao.bluetooth", R.drawable.module_apps_ic_bt_phone ), + + // 本地音乐 + LOCAL_MUSIC( "本地音乐", "com.nwd.android.music.ui", R.drawable.module_apps_ic_local_music ), + + // 天气 + WEATHER( "天气", "com.zhidao.weather", R.drawable.module_apps_ic_weather ), + + // 蓝牙音乐 + BT_MUSIC_NWD( "蓝牙音乐", "com.nwd.bt.music", R.drawable.module_apps_ic_bt_music ), + BT_MUSIC( "蓝牙音乐", "com.zhidao.bluetooth", R.drawable.module_apps_ic_bt_music ), + + // 高德地图 + AUTO_NAVI( "高德地图", "com.autonavi.amapauto", R.drawable.module_apps_ic_auto_navi ), + ; + + private String mName; + private String mPkg; + private int mIconResId; + + AppEnum( String name, String pkg, int iconResId ) { + this.mName = name; + this.mPkg = pkg; + this.mIconResId = iconResId; + } + + public String getPkg() { + return mPkg; + } + + public int getIconResId() { + return mIconResId; + } + + public String getName() { + return mName; + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppEnumHelper.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppEnumHelper.java new file mode 100644 index 0000000000..512ecf7411 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppEnumHelper.java @@ -0,0 +1,42 @@ +package com.mogo.module.apps.model; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author congtaowang + * @since 2020-02-12 + *

+ * 定制化的app + */ +public class AppEnumHelper { + + private static Map< String, AppEnum > sCustomizedApps = new HashMap<>(); + + static { + AppEnum[] customizedApps = AppEnum.values(); + for ( AppEnum customizedApp : customizedApps ) { + sCustomizedApps.put( customizedApp.getPkg(), customizedApp ); + } + } + + public static boolean isCustomizedApp( String pkg ) { + return sCustomizedApps.containsKey( pkg ); + } + + public static int getCustomizedAppIconResId( String pkg ) { + AppEnum appEnum = sCustomizedApps.get( pkg ); + if ( appEnum != null ) { + return appEnum.getIconResId(); + } + return 0; + } + + public static String getTargetName(String pkg){ + AppEnum appEnum = sCustomizedApps.get( pkg ); + if ( appEnum != null ) { + return appEnum.getName(); + } + return pkg; + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppInfo.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppInfo.java new file mode 100644 index 0000000000..62b2c34105 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppInfo.java @@ -0,0 +1,89 @@ +package com.mogo.module.apps.model; + +import android.graphics.drawable.Drawable; +import android.text.TextUtils; + +import java.util.Objects; + +/** + * @author congtaowang + * @since 2019-12-30 + *

+ * app 信息 + */ +public class AppInfo { + + private final String mName; + private final String mPackageName; + private final String mVersionName; + private final int mVersionCode; + private final Drawable mIcon; + private final int mIconResId; + private final int mTrackType; // 埋点类型 + + public AppInfo( String mName, String mPackageName, String mVersionName, int mVersionCode, Drawable mIcon, int mIconResId, int mTrackType ) { + this.mName = mName; + this.mPackageName = mPackageName; + this.mVersionName = mVersionName; + this.mVersionCode = mVersionCode; + this.mIcon = mIcon; + this.mIconResId = mIconResId; + this.mTrackType = mTrackType; + } + + public AppInfo( String mName, String mPackageName, String mVersionName, int mVersionCode, Drawable mIcon, int mIconResId ) { + this( mName, mPackageName, mVersionName, mVersionCode, mIcon, mIconResId, 0 ); + } + + public int getIconResId() { + return mIconResId; + } + + public String getName() { + return mName; + } + + public String getPackageName() { + return mPackageName; + } + + public String getVersionName() { + return mVersionName; + } + + public int getVersionCode() { + return mVersionCode; + } + + public Drawable getIcon() { + return mIcon; + } + + public int getTrackType() { + return mTrackType; + } + + @Override + public boolean equals( Object o ) { + if ( this == o ) return true; + if ( o == null || getClass() != o.getClass() ) return false; + AppInfo appInfo = ( AppInfo ) o; + return TextUtils.equals( mPackageName, appInfo.mPackageName ) + && TextUtils.equals( mName, appInfo.mName ); + } + + @Override + public int hashCode() { + return Objects.hash( mPackageName ); + } + + @Override + public String toString() { + return "AppInfo{" + + "mName='" + mName + '\'' + + ", mPackageName='" + mPackageName + '\'' + + ", mVersionName='" + mVersionName + '\'' + + ", mVersionCode=" + mVersionCode + + '}'; + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppLoadCallback.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppLoadCallback.java new file mode 100644 index 0000000000..af16816210 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppLoadCallback.java @@ -0,0 +1,15 @@ +package com.mogo.module.apps.model; + +import java.util.List; +import java.util.Map; + +/** + * @author congtaowang + * @since 2020-01-09 + *

+ * 描述 + */ +public interface AppLoadCallback { + + void onLoaded( Map< Integer, List< AppInfo > > appInfos ); +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppsModel.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppsModel.java new file mode 100644 index 0000000000..61c55a981d --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/AppsModel.java @@ -0,0 +1,206 @@ +package com.mogo.module.apps.model; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.graphics.drawable.Drawable; +import android.text.TextUtils; + +import com.mogo.module.apps.AppFilter; +import com.mogo.module.apps.AppFilterImpl; +import com.mogo.module.apps.AppsConst; +import com.mogo.module.apps.AppsListChangedLiveData; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @author congtaowang + * @since 2020-01-09 + *

+ * 加载并保存 app 列表 + */ +public class AppsModel { + + private static volatile AppsModel sInstance; + private Context mContext; + + private AppFilter mAppFilter; + + private Map< Integer, List< AppInfo > > mPagedApps = new HashMap<>(); + + private AppsModel( Context context ) { + mContext = context; + } + + public static AppsModel getInstance( Context context ) { + if ( sInstance == null ) { + synchronized ( AppsModel.class ) { + if ( sInstance == null ) { + sInstance = new AppsModel( context ); + } + } + } + return sInstance; + } + + + private AtomicBoolean mIsLoaded = new AtomicBoolean( false ); + + public synchronized void release() { + if ( mPagedApps != null ) { + mPagedApps.clear(); + } + mPagedApps = null; + mContext = null; + mAppFilter = null; + sInstance = null; + } + + public void load( AppLoadCallback callback ) { + if ( !mPagedApps.isEmpty() ) { + if ( callback != null ) { + callback.onLoaded( mPagedApps ); + } + return; + } + if ( mAppFilter == null ) { + mAppFilter = new AppFilterImpl( mContext ); + } + final PackageManager packageManager = mContext.getPackageManager(); + List< PackageInfo > packages = packageManager.getInstalledPackages( 0 ); + int counter = 0; + for ( int i = 0; i < packages.size(); ++i ) { + PackageInfo packageInfo = packages.get( i ); + if ( mAppFilter.filter( packageInfo ) ) { + continue; + } + int page = counter++ / AppsConst.TOTAL_SIZE_EACH_PAGE; + if ( !mPagedApps.containsKey( page ) ) { + mPagedApps.put( page, new ArrayList<>() ); + } + String appName = getApplicationName( packageManager, packageInfo ); + String packageName = packageInfo.packageName; + String versionName = packageInfo.versionName; + int versionCode = packageInfo.versionCode; + int iconResId = AppEnumHelper.getCustomizedAppIconResId( packageName ); + Drawable appIcon = null; + if ( iconResId == 0 ) { + appIcon = packageInfo.applicationInfo.loadIcon( packageManager ); + } + AppInfo appInfo = new AppInfo( appName, packageName, versionName, versionCode, appIcon, iconResId ); + mPagedApps.get( page ).add( appInfo ); + } + if ( callback != null ) { + callback.onLoaded( mPagedApps ); + } + mIsLoaded.set( true ); + } + + public void appAdded( String packageName ) { + if ( !mIsLoaded.get() ) { + return; + } + if ( TextUtils.isEmpty( packageName ) ) { + return; + } + if ( mPagedApps.isEmpty() ) { + return; + } + try { + final PackageManager packageManager = mContext.getPackageManager(); + PackageInfo packageInfo = packageManager.getPackageInfo( packageName, 0 ); + if ( !mAppFilter.filter( packageInfo ) ) { + String appName = getApplicationName( packageManager, packageInfo ); + String versionName = packageInfo.versionName; + int versionCode = packageInfo.versionCode; + Drawable appIcon = packageInfo.applicationInfo.loadIcon( packageManager ); + AppInfo appInfo = new AppInfo( appName, packageName, versionName, versionCode, appIcon, AppEnumHelper.getCustomizedAppIconResId( packageName ) ); + int pageIndex = getPageIndex( packageName, true ); + if ( !mPagedApps.containsKey( pageIndex ) ) { + mPagedApps.put( pageIndex, new ArrayList<>() ); + } + mPagedApps.get( pageIndex ).add( appInfo ); + } + AppsListChangedLiveData.getInstance().postValue( true ); + } catch ( PackageManager.NameNotFoundException e ) { + e.printStackTrace(); + } + } + + private String getApplicationName( PackageManager packageManager, PackageInfo packageInfo ) { + String name = packageManager.getApplicationLabel( packageInfo.applicationInfo ).toString(); + if ( AppEnumHelper.isCustomizedApp( packageInfo.packageName ) ) { + return AppEnumHelper.getTargetName( packageInfo.packageName ); + } + return name; + } + + private int getPageIndex( String packageName, boolean add ) { + int totalPages = mPagedApps.size(); + if ( add ) { + if ( totalPages == 0 ) { + return 0; + } else { + if ( mPagedApps.get( totalPages - 1 ).size() == AppsConst.TOTAL_SIZE_EACH_PAGE ) { + return totalPages; + } else { + return totalPages - 1; + } + } + } else { + if ( totalPages == 0 ) { + return -1; + } + int pageIndex = -1; + for ( int i = 0; i < totalPages; i++ ) { + for ( AppInfo appInfo : mPagedApps.get( i ) ) { + if ( TextUtils.equals( appInfo.getPackageName(), packageName ) ) { + pageIndex = i; + } + } + } + return pageIndex; + } + } + + public void appRemoved( String packageName ) { + if ( !mIsLoaded.get() ) { + return; + } + if ( TextUtils.isEmpty( packageName ) ) { + return; + } + try { + int pageIndex = getPageIndex( packageName, false ); + if ( pageIndex == -1 ) { + return; + } + int totalPages = mPagedApps.size(); + List< AppInfo > dynamicAppsList = new ArrayList<>(); + for ( int i = pageIndex; i < totalPages; i++ ) { + dynamicAppsList.addAll( mPagedApps.remove( i ) ); + } + int counter = 0; + for ( int i = 0; i < dynamicAppsList.size(); i++ ) { + AppInfo appInfo = dynamicAppsList.get( i ); + if ( TextUtils.equals( appInfo.getPackageName(), packageName ) ) { + continue; + } + int page = counter++ / AppsConst.TOTAL_SIZE_EACH_PAGE + pageIndex; + if ( !mPagedApps.containsKey( page ) ) { + mPagedApps.put( page, new ArrayList<>() ); + } + mPagedApps.get( page ).add( appInfo ); + } + AppsListChangedLiveData.getInstance().postValue( true ); + } catch ( Exception e ) { + e.printStackTrace(); + } + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/NavigatorApp.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/NavigatorApp.java new file mode 100644 index 0000000000..9681af74b6 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/NavigatorApp.java @@ -0,0 +1,32 @@ +package com.mogo.module.apps.model; + +import androidx.annotation.DrawableRes; + +/** + * @author congtaowang + * @since 2020-03-13 + *

+ * app + */ +public class NavigatorApp { + + @DrawableRes + public int mIconId; + @DrawableRes + public int mUncheckedIconId; + public String mName; + + public NavigatorApp( int mIconId, int mUncheckedIconId, String mName ) { + this.mIconId = mIconId; + this.mUncheckedIconId = mUncheckedIconId; + this.mName = mName; + } + + public int getIconId() { + return mIconId; + } + + public String getName() { + return mName; + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/NavigatorApps.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/NavigatorApps.java new file mode 100644 index 0000000000..12c4c92d54 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/NavigatorApps.java @@ -0,0 +1,40 @@ +package com.mogo.module.apps.model; + +import com.mogo.module.apps.R; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author congtaowang + * @since 2020-03-13 + *

+ * app + */ +public class NavigatorApps { + + private static AppInfo app = new AppInfo( "高德地图", "com.autonavi.amapauto", "", 0, null, R.drawable.module_apps_ic_navigator_navi, 1 ); + private static AppInfo app_ = new AppInfo( "高德地图", "com.autonavi.amapauto", "", 0, null, R.drawable.module_apps_ic_navigator_navi_disable, 1 ); +// private static AppInfo app2 = new AppInfo( "音乐", "com.tencent.wecarflow", "", 0, null, R.drawable.module_apps_ic_navigator_media, 2 ); + private static AppInfo app2 = new AppInfo( "音乐", "com.zhidao.music", "", 0, null, R.drawable.module_apps_ic_navigator_media, 2 ); + private static AppInfo app3 = new AppInfo( "车聊聊", "com.zhidao.imdemo", "", 0, null, R.drawable.module_apps_ic_navigator_im, 6 ); + private static AppInfo app4 = new AppInfo( "全部应用", "com.mogo.launcher.applist", "", 0, null, R.drawable.module_apps_ic_navigator_applist, 4 ); + + public static List< AppInfo > getApps() { + List< AppInfo > sApps = new ArrayList<>(); + sApps.add( app ); + sApps.add( app2 ); + sApps.add( app3 ); + sApps.add( app4 ); + return sApps; + } + + public static List< AppInfo > getAppsWithoutNavigation() { + List< AppInfo > sApps = new ArrayList<>(); + sApps.add( app ); + sApps.add( app2 ); + sApps.add( app3 ); + sApps.add( app4 ); + return sApps; + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/UnScannedApps.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/UnScannedApps.java new file mode 100644 index 0000000000..b55d9adb37 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/model/UnScannedApps.java @@ -0,0 +1,32 @@ +package com.mogo.module.apps.model; + +import com.mogo.module.common.utils.CarSeries; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author congtaowang + * @since 2020-04-02 + *

+ * 扫描不到的app + */ +public class UnScannedApps { + + private static List< AppInfo > sUnScannedApps = new ArrayList<>(); + + static { + if ( CarSeries.getSeries() == CarSeries.CAR_SERIES_F80X ) { + sUnScannedApps.add( new AppInfo( AppEnum.BT_PHONE.getName(), AppEnum.BT_PHONE.getPkg(), null, 0, null, AppEnum.BT_PHONE.getIconResId() ) ); + sUnScannedApps.add( new AppInfo( AppEnum.BT_MUSIC.getName(), AppEnum.BT_MUSIC.getPkg(), null, 0, null, AppEnum.BT_PHONE.getIconResId() ) ); + } else { + sUnScannedApps.add( new AppInfo( AppEnum.BT_PHONE_NWD.getName(), AppEnum.BT_PHONE_NWD.getPkg(), null, 0, null, AppEnum.BT_PHONE_NWD.getIconResId() ) ); + sUnScannedApps.add( new AppInfo( AppEnum.CanBus.getName(), AppEnum.CanBus.getPkg(), null, 0, null, AppEnum.CanBus.getIconResId() ) ); + } + } + + public static List< AppInfo > getUnScannedApps() { + return sUnScannedApps; + } + +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/receiver/AppInstallReceiver.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/receiver/AppInstallReceiver.java new file mode 100644 index 0000000000..1ea5fa4216 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/receiver/AppInstallReceiver.java @@ -0,0 +1,43 @@ + +package com.mogo.module.apps.receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; + +import com.mogo.module.apps.AppServiceHandler; +import com.mogo.module.apps.model.AppsModel; + +public class AppInstallReceiver extends BroadcastReceiver { + + @Override + public void onReceive( Context context, Intent intent ) { + if ( intent.getAction().equals( Intent.ACTION_PACKAGE_ADDED ) ) { + String packageName = intent.getData().getSchemeSpecificPart(); + AppsModel.getInstance( context ).appAdded( packageName ); + if ( TextUtils.equals( packageName, "com.zhidao.autopilot" ) ) { + AppServiceHandler.getApis().getAdasControllerApi().showADAS(); + } + } + if ( intent.getAction().equals( Intent.ACTION_PACKAGE_REMOVED ) ) { + String packageName = intent.getData().getSchemeSpecificPart(); + AppsModel.getInstance( context ).appRemoved( packageName ); + } + if ( intent.getAction().equals( Intent.ACTION_PACKAGE_REPLACED ) ) { + String packageName = intent.getData().getSchemeSpecificPart(); + if ( TextUtils.equals( packageName, "com.zhidao.autopilot" ) ) { + AppServiceHandler.getApis().getAdasControllerApi().showADAS(); + } + } + if ( intent.getAction().equals( Intent.ACTION_PACKAGE_CHANGED ) ) { + String packageName = intent.getData().getSchemeSpecificPart(); + } + if ( intent.getAction().equals( Intent.ACTION_PACKAGE_RESTARTED ) ) { + String packageName = intent.getData().getSchemeSpecificPart(); + } + if ( intent.getAction().equals( Intent.ACTION_PACKAGE_DATA_CLEARED ) ) { + String packageName = intent.getData().getSchemeSpecificPart(); + } + } +} \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/GridAverageView.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/GridAverageView.java new file mode 100644 index 0000000000..4f0607a279 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/GridAverageView.java @@ -0,0 +1,100 @@ +package com.mogo.module.apps.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; + +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.RecyclerView; + +/** + * Created by zeu on 2017/11/14. + */ + +public class GridAverageView extends ViewGroup { + int mColumnCount = 1; + int mRowCount = 1; + + /** + * 网格均等分布 + * + * @param context + */ + public GridAverageView( Context context ) { + super( context ); + } + + public GridAverageView( Context context, @Nullable AttributeSet attrs ) { + this( context, attrs, 0 ); + } + + public GridAverageView( Context context, @Nullable AttributeSet attrs, int defStyleAttr ) { + super( context, attrs, defStyleAttr ); + } + + public void setColumnCount( int mColumnCount ) { + this.mColumnCount = mColumnCount; + } + + public void setRowCount( int mRowCount ) { + this.mRowCount = mRowCount; + } + + public int getColumnCount() { + return mColumnCount; + } + + public int getRowCount() { + return mRowCount; + } + + @Override + protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec ) { + int averageWidth = MeasureSpec.getSize( widthMeasureSpec ) / getColumnCount(); + int averageHeight = MeasureSpec.getSize( heightMeasureSpec ) / getRowCount(); + for ( int i = 0; i < getChildCount(); i++ ) { + View child = this.getChildAt( i ); + child.measure( MeasureSpec.makeMeasureSpec( averageWidth, MeasureSpec.EXACTLY ), MeasureSpec.makeMeasureSpec( averageHeight, MeasureSpec.EXACTLY ) ); + } + setMeasuredDimension( widthMeasureSpec, heightMeasureSpec ); + super.onMeasure( widthMeasureSpec, heightMeasureSpec ); + } + + @Override + protected void onLayout( boolean changed, int l, int t, int r, int b ) { + int width = r - l - getPaddingLeft() - getPaddingRight(); + int height = b - t - getPaddingBottom() - getPaddingTop(); + int childWidth = width / getColumnCount(); + int childHeight = height / getRowCount(); + + int size = getChildCount(); + for ( int i = 0; i < size; i++ ) { + View child = getChildAt( i ); + int row = i / getColumnCount(); + int col = i % getColumnCount(); + int cl = 0 + childWidth * col; + int cr = cl + childWidth; + + int ct = 0 + childHeight * row; + int cb = ct + childHeight; + child.layout( cl, ct, cr, cb ); + } + } + + public void setAdapter( BaseAdapter adapter ) { + if ( adapter == null ) { + return; + } + final int size = adapter.getCount(); + if ( size <= 0 ) { + return; + } + for ( int i = 0; i < size; i++ ) { + View childView = adapter.getView( i, null, this ); + addView( childView ); + requestLayout(); + } + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/GridViewPagerScroller.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/GridViewPagerScroller.java new file mode 100644 index 0000000000..3d7116ad58 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/GridViewPagerScroller.java @@ -0,0 +1,31 @@ +package com.mogo.module.apps.view; + +import android.content.Context; +import android.view.animation.Interpolator; +import android.widget.Scroller; + +public class GridViewPagerScroller extends Scroller { + private int duration; + + public GridViewPagerScroller( Context context) { + super(context); + } + + public GridViewPagerScroller( Context context, Interpolator interpolator) { + super(context, interpolator); + } + + public void setDuration(int duration) { + this.duration = duration; + } + + @Override + public void startScroll(int startX, int startY, int dx, int dy) { + super.startScroll(startX, startY, dx, dy,this.duration); + } + + @Override + public void startScroll(int startX, int startY, int dx, int dy, int duration) { + super.startScroll(startX, startY, dx, dy, this.duration); + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/OnAiAssistClickListener.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/OnAiAssistClickListener.java new file mode 100644 index 0000000000..032ea2ad8e --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/OnAiAssistClickListener.java @@ -0,0 +1,57 @@ +package com.mogo.module.apps.view; + +import android.view.View; + +import com.mogo.commons.debug.DebugConfig; +import com.mogo.commons.device.Devices; +import com.mogo.commons.voice.AIAssist; +import com.mogo.utils.TipToast; + +public +/** + * @author congtaowang + * @since 2020/6/9 + * + * 如果已经激活设备,则按照正常流程打开语音,否则需要连续点击5下才能打开 + */ +class OnAiAssistClickListener implements View.OnClickListener { + + public static final int TOTAL_CLICK_AMOUNT = 5; + public static final int INTERVAL = 2_000 / TOTAL_CLICK_AMOUNT; + + private int mClickCounter = 0; + private long mLastClickTime = 0L; + + private boolean mDebugModeOpen = false; + + @Override + public void onClick( View v ) { + if ( Devices.isBind() || !DebugConfig.isActiveAIAssistFlag() ) { + AIAssist.startAssistant( v.getContext() ); + } else { + if ( mDebugModeOpen ) { + AIAssist.startAssistant( v.getContext(), 1 ); + return; + } + if ( mClickCounter == 0 ) { + mLastClickTime = System.currentTimeMillis(); + mClickCounter++; + } else { + if ( mClickCounter == TOTAL_CLICK_AMOUNT ) { + AIAssist.startAssistant( v.getContext(), 2 ); + TipToast.shortTip( "开启语音调试" ); + mClickCounter = 0; + mLastClickTime = 0L; + mDebugModeOpen = true; + } else if ( System.currentTimeMillis() - mLastClickTime > INTERVAL ) { + mClickCounter = 0; + TipToast.shortTip( "请在2秒内连续点击5次打开语音调试模式" ); + } else { + mClickCounter++; + } + mLastClickTime = System.currentTimeMillis(); + } + } + } + +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/PagerIndicator.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/PagerIndicator.java new file mode 100644 index 0000000000..20efc01576 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/PagerIndicator.java @@ -0,0 +1,41 @@ +package com.mogo.module.apps.view; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +import com.mogo.module.apps.R; + +/** + * @author congtaowang + * @since 2020-02-11 + *

+ * 描述 + */ +public class PagerIndicator extends LinearLayout implements PagerSlidingTabStripV2.SelectedState { + + private View mIndicator; + + public PagerIndicator( Context context ) { + this( context, null ); + } + + public PagerIndicator( Context context, @Nullable AttributeSet attrs ) { + this( context, attrs, 0 ); + } + + public PagerIndicator( Context context, @Nullable AttributeSet attrs, int defStyleAttr ) { + super( context, attrs, defStyleAttr ); + LayoutInflater.from( context ).inflate( R.layout.module_apps_page_indicator, this, true ); + mIndicator = findViewById( R.id.module_apps_id_indicator_dot ); + } + + @Override + public void setSelectedState( boolean isSelected ) { + mIndicator.setSelected( isSelected ); + } +} diff --git a/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/PagerSlidingTabStripV2.java b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/PagerSlidingTabStripV2.java new file mode 100644 index 0000000000..70443ce345 --- /dev/null +++ b/modules/mogo-module-apps/src/main/java/com/mogo/module/apps/view/PagerSlidingTabStripV2.java @@ -0,0 +1,763 @@ +/* + * Copyright (C) 2013 Andreas Stuetz + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mogo.module.apps.view; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Paint.Style; +import android.graphics.Typeface; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextPaint; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; +import android.widget.HorizontalScrollView; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.viewpager.widget.ViewPager; + + +import com.mogo.module.apps.R; +import com.mogo.utils.WindowUtils; + +import java.util.Locale; + +/** + * Reference : http://doc.okbase.net/HarryWeasley/archive/121430.html + */ +public class PagerSlidingTabStripV2 extends HorizontalScrollView { + + public interface IconTabProvider { + public int getPageIconResId( int position ); + } + + public interface ViewTabProvider { + public View getPageTabView( Context context, int position ); + } + + public interface SelectedState { + void setSelectedState( boolean isSelected ); + } + + // @formatter:off + private static final int[] ATTRS = new int[]{ + android.R.attr.textSize, + android.R.attr.textColor + }; + // @formatter:on + + public interface OnBeforeTabAction { + boolean doAction( int position ); + } + + private LinearLayout.LayoutParams defaultTabLayoutParams; + private LinearLayout.LayoutParams expandedTabLayoutParams; + + private final PageListener pageListener = new PageListener(); + public ViewPager.OnPageChangeListener delegatePageListener; + + private LinearLayout tabsContainer; + private ViewPager pager; + + private int tabCount; + + private int currentPosition = 0; + private int selectedPosition = 0; + private float currentPositionOffset = 0f; + + private Paint rectPaint; + private Paint dividerPaint; + + private int indicatorColor = 0xFF666666; + private int underlineColor = 0x1A000000; + private int dividerColor = 0x1A000000; + + private boolean shouldExpand = false; + private boolean textAllCaps = true; + + private int scrollOffset = 52; + private int indicatorHeight = 8; + private int underlineHeight = 2; + private int dividerPadding = 12; + private int tabPadding = 24; + private int dividerWidth = 1; + private int indicatorMarginBottom = 0; + private int indicatorMarginLeft = 0; + private int indicatorMarginRight = 0; + + private int tabTextSize = 13; + private int tabTextColor = 0xFF666666; + private int selectedTabTextColor = 0xFF666666; + + private Typeface tabTypeface = null; + private int tabTypefaceStyle = Typeface.NORMAL; + + private int lastScrollX = 0; + + private int tabBackgroundResId = R.drawable.module_apps_pager_sliding_background_tab; + + public static final int INDICATOR_MODE_UNDERLINE = -1; + public static final int INDICATOR_MODE_SHADOW = 1; + public static final int INDICATOR_MODE_RES = 2; + private int indicatorMode = INDICATOR_MODE_SHADOW; + + private Drawable indicatorRes; + + public static final int INDICATOR_FIT_MODE_AUTO = 0; + public static final int INDICATOR_FIT_MODE_FIXED = 1; + private int indicatorFitMode = INDICATOR_FIT_MODE_AUTO; + + private float indicatorFixedSize = 0; + + private Locale locale; + + private OnBeforeTabAction onBeforeTabAction; + private boolean openPadding = false; + + + public boolean isOpenPadding() { + return openPadding; + } + + public void setOpenPadding( boolean openPadding ) { + this.openPadding = openPadding; + } + + public PagerSlidingTabStripV2( Context context ) { + this( context, null ); + } + + public PagerSlidingTabStripV2( Context context, AttributeSet attrs ) { + this( context, attrs, 0 ); + } + + public PagerSlidingTabStripV2( Context context, AttributeSet attrs, int defStyle ) { + super( context, attrs, defStyle ); + + setFillViewport( true ); + setWillNotDraw( false ); + + tabsContainer = new LinearLayout( context ); + tabsContainer.setOrientation( LinearLayout.HORIZONTAL ); + tabsContainer.setLayoutParams( new LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT ) ); + addView( tabsContainer ); + + DisplayMetrics dm = getResources().getDisplayMetrics(); + + scrollOffset = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm ); + indicatorHeight = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm ); + underlineHeight = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm ); + dividerPadding = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm ); + tabPadding = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm ); + dividerWidth = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm ); + tabTextSize = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm ); + indicatorMarginBottom = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, indicatorMarginBottom, dm ); + indicatorMarginLeft = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, indicatorMarginLeft, dm ); + indicatorMarginRight = ( int ) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, indicatorMarginRight, dm ); + + // get system attrs (android:textSize and android:textColor) + + TypedArray a = context.obtainStyledAttributes( attrs, ATTRS ); + + tabTextSize = a.getDimensionPixelSize( 0, tabTextSize ); + tabTextColor = a.getColor( 1, tabTextColor ); + + a.recycle(); + + // get custom attrs + + a = context.obtainStyledAttributes( attrs, R.styleable.PagerSlidingTabStripV2 ); + + indicatorColor = a.getColor( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorColor, indicatorColor ); + //tab文字选中时的颜色,默认和滑动指示器的颜色一致 + selectedTabTextColor = a.getColor( R.styleable.PagerSlidingTabStripV2_pstsV2SelectedTabTextColor, indicatorColor ); + tabTextColor = a.getColor( R.styleable.PagerSlidingTabStripV2_pstsV2TabTextColorValue, tabTextColor ); + underlineColor = a.getColor( R.styleable.PagerSlidingTabStripV2_pstsV2UnderlineColor, underlineColor ); + dividerColor = a.getColor( R.styleable.PagerSlidingTabStripV2_pstsV2DividerColor, dividerColor ); + indicatorHeight = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorHeight, indicatorHeight ); + underlineHeight = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2UnderlineHeight, underlineHeight ); + dividerPadding = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2DividerPadding, dividerPadding ); + tabPadding = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2TabPaddingLeftRight, tabPadding ); + tabBackgroundResId = a.getResourceId( R.styleable.PagerSlidingTabStripV2_pstsV2TabBackground, tabBackgroundResId ); + shouldExpand = a.getBoolean( R.styleable.PagerSlidingTabStripV2_pstsV2ShouldExpand, shouldExpand ); + scrollOffset = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2ScrollOffset, scrollOffset ); + textAllCaps = a.getBoolean( R.styleable.PagerSlidingTabStripV2_pstsV2TextAllCaps, textAllCaps ); + indicatorMarginBottom = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorMarginBottom, indicatorMarginBottom ); + indicatorMarginLeft = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorMarginLeft, indicatorMarginLeft ); + indicatorMarginRight = a.getDimensionPixelSize( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorMarginRight, indicatorMarginRight ); + indicatorMode = a.getInt( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorMode, INDICATOR_MODE_SHADOW ); + indicatorRes = a.getDrawable( R.styleable.PagerSlidingTabStripV2_pstsV2IndicatorRes ); + a.recycle(); + + rectPaint = new Paint(); + rectPaint.setAntiAlias( true ); + rectPaint.setStyle( Style.FILL ); + + dividerPaint = new Paint(); + dividerPaint.setAntiAlias( true ); + dividerPaint.setStrokeWidth( dividerWidth ); + + defaultTabLayoutParams = new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT ); + expandedTabLayoutParams = new LinearLayout.LayoutParams( 0, LayoutParams.MATCH_PARENT, 1.0f ); + + if ( locale == null ) { + locale = getResources().getConfiguration().locale; + } + } + + public OnBeforeTabAction getOnBeforeTabAction() { + return onBeforeTabAction; + } + + public void setOnBeforeTabAction( OnBeforeTabAction onBeforeTabAction ) { + this.onBeforeTabAction = onBeforeTabAction; + } + + public void setViewPager( ViewPager pager ) { + this.pager = pager; + this.currentPosition = this.selectedPosition = pager.getCurrentItem(); + + if ( pager.getAdapter() == null ) { + throw new IllegalStateException( "ViewPager does not have adapter instance." ); + } + + pager.removeOnPageChangeListener( pageListener ); + pager.addOnPageChangeListener( pageListener ); + + notifyDataSetChanged(); + } + + public void setOnPageChangeListener( ViewPager.OnPageChangeListener listener ) { + this.delegatePageListener = listener; + } + + public void notifyDataSetChanged() { + + indicatorLineOffset = -1; + tabsContainer.removeAllViews(); + + tabCount = pager.getAdapter().getCount(); + + for ( int i = 0; i < tabCount; i++ ) { + + if ( pager.getAdapter() instanceof ViewTabProvider ) { + addViewTab( i, ( ( ViewTabProvider ) pager.getAdapter() ).getPageTabView( getContext(), i ) ); + } else { + addTextTab( i, TextUtils.isEmpty( pager.getAdapter().getPageTitle( i ) ) ? "" : pager.getAdapter().getPageTitle( i ).toString() ); + } + + } + + updateTabStyles(); + + getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { + + @Override + public void onGlobalLayout() { + getViewTreeObserver().removeGlobalOnLayoutListener( this ); + currentPosition = pager.getCurrentItem(); + scrollToChild( currentPosition, 0 ); + } + } ); + + } + + private void addTextTab( final int position, String title ) { + + TextView tab = new TextView( getContext() ); + tab.setText( title ); + tab.setGravity( Gravity.CENTER ); + tab.setSingleLine(); + tab.setPadding( WindowUtils.dip2px( getContext(), 10 ), + WindowUtils.dip2px( getContext(), 3 ), + WindowUtils.dip2px( getContext(), 10 ), + WindowUtils.dip2px( getContext(), 3 ) ); + + LinearLayout linearLayout = new LinearLayout( getContext() ); + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT ); + linearLayout.addView( tab, layoutParams ); + linearLayout.setGravity( Gravity.CENTER ); + addTab( position, linearLayout ); + } + + private void addIconTab( final int position, int resId ) { + + ImageButton tab = new ImageButton( getContext() ); + tab.setImageResource( resId ); + + addTab( position, tab ); + + } + + private void addViewTab( final int position, View v ) { + addTab( position, v ); + } + + public void setCurrentTab( final int position ) { + pager.post( new Runnable() { + @Override + public void run() { + pager.setCurrentItem( position, false ); + } + } ); + } + + private void addTab( final int position, View tab ) { + tab.setFocusable( true ); + tab.setOnClickListener( new OnClickListener() { + @Override + public void onClick( View v ) { + if ( getOnBeforeTabAction() != null ) { + if ( getOnBeforeTabAction().doAction( position ) ) { + pager.setCurrentItem( position, false ); + } + } else { + pager.setCurrentItem( position, false ); + } + } + } ); + + if ( openPadding ) { + tab.setPadding( position == 0 ? 0 : tabPadding, 0, tabPadding, 0 ); + } + + tabsContainer.addView( tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams ); + } + + private void updateTabStyles() { + + for ( int i = 0; i < tabCount; i++ ) { + + View v = tabsContainer.getChildAt( i ); + + if ( v instanceof SelectedState ) { + ( ( SelectedState ) v ).setSelectedState( i == selectedPosition ); + } else if ( v instanceof LinearLayout ) { + + TextView tab = ( TextView ) ( ( LinearLayout ) v ).getChildAt( 0 ); + tab.setTextSize( TypedValue.COMPLEX_UNIT_PX, tabTextSize ); + tab.setTypeface( tabTypeface, tabTypefaceStyle ); + tab.setTextColor( tabTextColor ); + + if ( textAllCaps ) { + tab.setAllCaps( true ); + } + + if ( i == selectedPosition ) { + tab.setTextColor( selectedTabTextColor ); + if ( indicatorMode == INDICATOR_MODE_SHADOW ) { + tab.setBackgroundResource( R.drawable.module_apps_shape_deep_blue ); + } + } else { + tab.setTextColor( tabTextColor ); + tab.setBackgroundResource( 0 ); + } + } + } + } + + private void scrollToChild( int position, int offset ) { + + if ( tabCount == 0 ) { + return; + } + + int newScrollX = tabsContainer.getChildAt( position ).getLeft() + offset; + + if ( position > 0 || offset > 0 ) { + newScrollX -= scrollOffset; + } + + if ( newScrollX != lastScrollX ) { + lastScrollX = newScrollX; + scrollTo( newScrollX, 0 ); + } + + } + + @Override + protected void onDraw( Canvas canvas ) { + super.onDraw( canvas ); + + if ( isInEditMode() || tabCount == 0 ) { + return; + } + + final int height = getHeight(); + + + // draw indicator line + + rectPaint.setColor( indicatorColor ); + + // default: line below current tab + View currentTab = tabsContainer.getChildAt( currentPosition ); + float lineLeft = currentTab.getLeft(); + float lineRight = currentTab.getRight(); + + // if there is an offset, start interpolating left and right coordinates between current and next tab + if ( currentPositionOffset > 0f && currentPosition < tabCount - 1 ) { + + View nextTab = tabsContainer.getChildAt( currentPosition + 1 ); + final float nextTabLeft = nextTab.getLeft(); + final float nextTabRight = nextTab.getRight(); + + lineLeft = ( currentPositionOffset * nextTabLeft + ( 1f - currentPositionOffset ) * lineLeft ); + lineRight = ( currentPositionOffset * nextTabRight + ( 1f - currentPositionOffset ) * lineRight ); + } + + if ( indicatorMode == INDICATOR_MODE_UNDERLINE ) { + float lineOffset = getLineOffset(); + float left, right, top, bottom; + if ( indicatorFitMode == INDICATOR_FIT_MODE_AUTO ) { + left = lineLeft + lineOffset + indicatorMarginLeft; + right = lineRight - lineOffset - indicatorMarginRight; + top = height - indicatorHeight - indicatorMarginBottom; + bottom = height - indicatorMarginBottom; + } else { + left = lineLeft + lineOffset; + right = lineRight - lineOffset; + top = height - indicatorHeight - indicatorMarginBottom; + bottom = height - indicatorMarginBottom; + } + + if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ) { + canvas.drawRoundRect( left, top, right, bottom, 90, 90, rectPaint ); + } else { + canvas.drawRect( left, top, right, bottom, rectPaint ); + } + } + + if ( indicatorMode == INDICATOR_MODE_RES ) { + if ( indicatorRes != null ) { + int lineOffset = ( int ) getLineOffset(); + int left, right, top, bottom; + int width = indicatorRes.getIntrinsicWidth(); + left = ( int ) lineLeft + lineOffset; + right = ( int ) lineRight - lineOffset; + top = height - indicatorRes.getIntrinsicHeight() - indicatorMarginBottom; + left = left + ( right - left - width ) / 2; + right = left + width; + bottom = height - indicatorMarginBottom; + indicatorRes.setBounds( left, top, right, bottom ); + indicatorRes.draw( canvas ); + } + } + + // draw underline + + rectPaint.setColor( underlineColor ); + canvas.drawRect( 0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint ); + + // draw divider + + dividerPaint.setColor( dividerColor ); + for ( int i = 0; i < tabCount - 1; i++ ) { + View tab = tabsContainer.getChildAt( i ); + canvas.drawLine( tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint ); + } + } + + private float indicatorLineOffset = -1; + + private float getLineOffset() { + + if ( tabsContainer.getChildCount() == 0 ) { + return 0; + } + if ( !shouldExpand ) { + return 0; + } + if ( indicatorLineOffset != -1 ) { + return indicatorLineOffset; + } + + float minViewMeasuredWidth = tabsContainer.getChildAt( 0 ).getMeasuredWidth(); + float minContentWidth = getTabContentWidth( tabsContainer.getChildAt( 0 ) ); + for ( int i = 1; i < tabsContainer.getChildCount(); i++ ) { + float nextContentWidth = getTabContentWidth( tabsContainer.getChildAt( i ) ); + if ( minContentWidth > nextContentWidth ) { + minContentWidth = nextContentWidth; + } + } + float offset = ( minViewMeasuredWidth - minContentWidth ) / 2; + return indicatorLineOffset = offset == 0 ? WindowUtils.dip2px( getContext(), 25 ) : offset; + } + + private float getTabContentWidth( View tab ) { + if ( tab instanceof TextView ) { + TextPaint paint = ( ( TextView ) tab ).getPaint(); + return paint.measureText( ( ( TextView ) tab ).getText().toString() ); + } + return tab.getMeasuredWidth(); + } + + private class PageListener implements ViewPager.OnPageChangeListener { + + @Override + public void onPageScrolled( int position, float positionOffset, int positionOffsetPixels ) { + + currentPosition = position; + currentPositionOffset = positionOffset; + + scrollToChild( position, ( int ) ( positionOffset * tabsContainer.getChildAt( position ).getWidth() ) ); + + invalidate(); + + if ( delegatePageListener != null ) { + delegatePageListener.onPageScrolled( position, positionOffset, positionOffsetPixels ); + } + } + + @Override + public void onPageScrollStateChanged( int state ) { + if ( state == ViewPager.SCROLL_STATE_IDLE ) { + scrollToChild( pager.getCurrentItem(), 0 ); + } + + if ( delegatePageListener != null ) { + delegatePageListener.onPageScrollStateChanged( state ); + } + } + + @Override + public void onPageSelected( int position ) { + selectedPosition = position; + updateTabStyles(); + if ( delegatePageListener != null ) { + delegatePageListener.onPageSelected( position ); + } + } + + } + + public void setIndicatorColor( int indicatorColor ) { + this.indicatorColor = indicatorColor; + invalidate(); + } + + public void setIndicatorColorResource( int resId ) { + this.indicatorColor = getResources().getColor( resId ); + invalidate(); + } + + public int getIndicatorColor() { + return this.indicatorColor; + } + + public void setIndicatorHeight( int indicatorLineHeightPx ) { + this.indicatorHeight = indicatorLineHeightPx; + invalidate(); + } + + public int getIndicatorHeight() { + return indicatorHeight; + } + + public void setUnderlineColor( int underlineColor ) { + this.underlineColor = underlineColor; + invalidate(); + } + + public void setUnderlineColorResource( int resId ) { + this.underlineColor = getResources().getColor( resId ); + invalidate(); + } + + public int getUnderlineColor() { + return underlineColor; + } + + public void setDividerColor( int dividerColor ) { + this.dividerColor = dividerColor; + invalidate(); + } + + public void setDividerColorResource( int resId ) { + this.dividerColor = getResources().getColor( resId ); + invalidate(); + } + + public int getDividerColor() { + return dividerColor; + } + + public void setUnderlineHeight( int underlineHeightPx ) { + this.underlineHeight = underlineHeightPx; + invalidate(); + } + + public int getUnderlineHeight() { + return underlineHeight; + } + + public void setDividerPadding( int dividerPaddingPx ) { + this.dividerPadding = dividerPaddingPx; + invalidate(); + } + + public int getDividerPadding() { + return dividerPadding; + } + + public void setScrollOffset( int scrollOffsetPx ) { + this.scrollOffset = scrollOffsetPx; + invalidate(); + } + + public int getScrollOffset() { + return scrollOffset; + } + + public void setShouldExpand( boolean shouldExpand ) { + this.shouldExpand = shouldExpand; + notifyDataSetChanged(); + } + + public boolean getShouldExpand() { + return shouldExpand; + } + + public boolean isTextAllCaps() { + return textAllCaps; + } + + public void setAllCaps( boolean textAllCaps ) { + this.textAllCaps = textAllCaps; + } + + public void setTextSize( int textSizePx ) { + this.tabTextSize = textSizePx; + updateTabStyles(); + } + + public int getTextSize() { + return tabTextSize; + } + + public void setTextColor( int textColor ) { + this.tabTextColor = textColor; + updateTabStyles(); + } + + public void setTextColorResource( int resId ) { + this.tabTextColor = getResources().getColor( resId ); + updateTabStyles(); + } + + public int getTextColor() { + return tabTextColor; + } + + public void setSelectedTextColor( int textColor ) { + this.selectedTabTextColor = textColor; + updateTabStyles(); + } + + public void setSelectedTextColorResource( int resId ) { + this.selectedTabTextColor = getResources().getColor( resId ); + updateTabStyles(); + } + + public int getSelectedTextColor() { + return selectedTabTextColor; + } + + public void setTypeface( Typeface typeface, int style ) { + this.tabTypeface = typeface; + this.tabTypefaceStyle = style; + updateTabStyles(); + } + + public void setTabBackground( int resId ) { + this.tabBackgroundResId = resId; + updateTabStyles(); + } + + public int getTabBackground() { + return tabBackgroundResId; + } + + public void setTabPaddingLeftRight( int paddingPx ) { + this.tabPadding = paddingPx; + updateTabStyles(); + } + + public int getTabPaddingLeftRight() { + return tabPadding; + } + + @Override + public void onRestoreInstanceState( Parcelable state ) { + SavedState savedState = ( SavedState ) state; + super.onRestoreInstanceState( savedState.getSuperState() ); + currentPosition = savedState.currentPosition; + requestLayout(); + } + + @Override + public Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + SavedState savedState = new SavedState( superState ); + savedState.currentPosition = currentPosition; + return savedState; + } + + static class SavedState extends BaseSavedState { + int currentPosition; + + public SavedState( Parcelable superState ) { + super( superState ); + } + + private SavedState( Parcel in ) { + super( in ); + currentPosition = in.readInt(); + } + + @Override + public void writeToParcel( Parcel dest, int flags ) { + super.writeToParcel( dest, flags ); + dest.writeInt( currentPosition ); + } + + public static final Creator< SavedState > CREATOR = new Creator< SavedState >() { + @Override + public SavedState createFromParcel( Parcel in ) { + return new SavedState( in ); + } + + @Override + public SavedState[] newArray( int size ) { + return new SavedState[size]; + } + }; + } + +} diff --git a/modules/mogo-module-apps/src/main/res/anim/module_apps_anim_enter.xml b/modules/mogo-module-apps/src/main/res/anim/module_apps_anim_enter.xml new file mode 100644 index 0000000000..4c8c5e9c52 --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/anim/module_apps_anim_enter.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/anim/module_apps_anim_exit.xml b/modules/mogo-module-apps/src/main/res/anim/module_apps_anim_exit.xml new file mode 100644 index 0000000000..d4173135df --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/anim/module_apps_anim_exit.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/ic_kuwo.webp b/modules/mogo-module-apps/src/main/res/drawable-ldpi/ic_kuwo.webp new file mode 100644 index 0000000000..82330db5fa Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/ic_kuwo.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_apps.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_apps.png new file mode 100644 index 0000000000..a56017fd57 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_apps.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_aux.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_aux.png new file mode 100644 index 0000000000..425894b2c0 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_aux.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_bt.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_bt.png new file mode 100644 index 0000000000..595b087455 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_bt.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_bt_phone.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_bt_phone.png new file mode 100644 index 0000000000..65b23ed5dd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_bt_phone.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_canbus.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_canbus.png new file mode 100644 index 0000000000..f29ce31281 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_canbus.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_car_setting.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_car_setting.png new file mode 100644 index 0000000000..3f8c6f8483 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_car_setting.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_car_settings.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_car_settings.png new file mode 100644 index 0000000000..cd4253095b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_car_settings.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_carcorder.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_carcorder.png new file mode 100644 index 0000000000..076e301e62 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_carcorder.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_chat.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_chat.png new file mode 100644 index 0000000000..d099b857d9 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_chat.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_chat_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_chat_unchecked.png new file mode 100644 index 0000000000..d76595c392 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_chat_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_clean_master.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_clean_master.png new file mode 100644 index 0000000000..594b36fa2e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_clean_master.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_default_icon.png similarity index 100% rename from app/src/main/res/mipmap-hdpi/ic_launcher.png rename to modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_default_icon.png diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_equlizer.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_equlizer.png new file mode 100644 index 0000000000..d9e94aa25b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_equlizer.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fleet.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fleet.png new file mode 100644 index 0000000000..f9a9cb0b91 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fleet.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fm.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fm.png new file mode 100644 index 0000000000..bfec997202 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fm.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fota.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fota.png new file mode 100644 index 0000000000..1eb98da08b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fota.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fresh_things.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fresh_things.png new file mode 100644 index 0000000000..41ec3ad07d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_fresh_things.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_icon_map.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_icon_map.png new file mode 100644 index 0000000000..a4f8d3f16e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_icon_map.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_im.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_im.png new file mode 100644 index 0000000000..9a08151023 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_im.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_interest.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_interest.png new file mode 100644 index 0000000000..d2fac8cf3a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_interest.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_interest_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_interest_unchecked.png new file mode 100644 index 0000000000..c7d89c68ad Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_interest_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_local_video.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_local_video.png new file mode 100644 index 0000000000..813c00b262 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_local_video.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_lrts.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_lrts.png new file mode 100644 index 0000000000..b8b9cc814b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_lrts.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_media_center.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_media_center.png new file mode 100644 index 0000000000..044ceb0683 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_media_center.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_media_center_checked.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_media_center_checked.png new file mode 100644 index 0000000000..fa1b977bfa Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_media_center_checked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigation.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigation.png new file mode 100644 index 0000000000..f192abed11 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigation.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_applist.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_applist.png new file mode 100644 index 0000000000..f884758d3d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_applist.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_im.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_im.png new file mode 100644 index 0000000000..7a959f1ca1 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_im.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_media.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_media.png new file mode 100644 index 0000000000..d9f6df313d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_media.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_navi.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_navi.png new file mode 100644 index 0000000000..2401ce7c2a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_navi.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_navi_disable.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_navi_disable.png new file mode 100644 index 0000000000..3df9f14026 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_navigator_navi_disable.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_news.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_news.png new file mode 100644 index 0000000000..c86bcef363 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_news.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_news_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_news_unchecked.png new file mode 100644 index 0000000000..77343ff931 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_news_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_online_car.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_online_car.png new file mode 100644 index 0000000000..9922237c77 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_online_car.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_online_car_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_online_car_unchecked.png new file mode 100644 index 0000000000..318e9535a0 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_online_car_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_personal_center.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_personal_center.png new file mode 100644 index 0000000000..14f9134a80 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_personal_center.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_qiyi.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_qiyi.png new file mode 100644 index 0000000000..1d885be37f Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_qiyi.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_qq_music.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_qq_music.png new file mode 100644 index 0000000000..dea1154a13 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_qq_music.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_retract.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_retract.png new file mode 100644 index 0000000000..24d42281c4 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_retract.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_road_condition.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_road_condition.png new file mode 100644 index 0000000000..12c5d954b8 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_road_condition.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_stee_product.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_stee_product.png new file mode 100644 index 0000000000..e3040f195f Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_stee_product.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_tanlu.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_tanlu.png new file mode 100644 index 0000000000..32afef191d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_tanlu.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_tanlu_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_tanlu_unchecked.png new file mode 100644 index 0000000000..4b451a1178 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_tanlu_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_we_car_flow.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_we_car_flow.png new file mode 100644 index 0000000000..95734bb594 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_we_car_flow.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_wechat.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_wechat.png new file mode 100644 index 0000000000..136b3e6ab8 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_wechat.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_welfare.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_welfare.png new file mode 100644 index 0000000000..dc951e6133 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_welfare.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_ximalaya.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_ximalaya.png new file mode 100644 index 0000000000..9c55842f45 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/module_apps_ic_ximalaya.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00000.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00000.png new file mode 100644 index 0000000000..fb93d34e52 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00000.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00001.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00001.png new file mode 100644 index 0000000000..2d90014c88 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00001.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00002.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00002.png new file mode 100644 index 0000000000..cebabd17dd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00002.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00003.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00003.png new file mode 100644 index 0000000000..7de16583b3 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00003.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00004.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00004.png new file mode 100644 index 0000000000..889e1fda6a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00004.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00005.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00005.png new file mode 100644 index 0000000000..af4a3d909c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00005.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00006.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00006.png new file mode 100644 index 0000000000..0c30ddd100 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00006.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00007.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00007.png new file mode 100644 index 0000000000..c22e60f799 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00007.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00008.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00008.png new file mode 100644 index 0000000000..5fdd402211 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00008.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00009.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00009.png new file mode 100644 index 0000000000..59a89a6a49 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00009.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00010.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00010.png new file mode 100644 index 0000000000..fd41cd22e5 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00010.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00011.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00011.png new file mode 100644 index 0000000000..feccc9606d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00011.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00012.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00012.png new file mode 100644 index 0000000000..0c8586d2d4 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00012.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00013.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00013.png new file mode 100644 index 0000000000..00d78703cd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00013.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00014.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00014.png new file mode 100644 index 0000000000..a0dae668ff Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00014.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00015.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00015.png new file mode 100644 index 0000000000..d5c4162e35 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00015.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00016.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00016.png new file mode 100644 index 0000000000..9b942cde66 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00016.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00017.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00017.png new file mode 100644 index 0000000000..e2e429f2ad Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00017.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00018.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00018.png new file mode 100644 index 0000000000..058e5dbf6e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00018.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00019.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00019.png new file mode 100644 index 0000000000..e992640008 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00019.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00020.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00020.png new file mode 100644 index 0000000000..974e26deca Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00020.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00021.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00021.png new file mode 100644 index 0000000000..0582f43235 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00021.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00022.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00022.png new file mode 100644 index 0000000000..3460520479 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00022.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00023.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00023.png new file mode 100644 index 0000000000..0816cb4016 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00023.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00024.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00024.png new file mode 100644 index 0000000000..0a42e16b7e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00024.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00025.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00025.png new file mode 100644 index 0000000000..592137d15f Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00025.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00026.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00026.png new file mode 100644 index 0000000000..25d14c902b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00026.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00027.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00027.png new file mode 100644 index 0000000000..ec90bcf254 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00027.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00028.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00028.png new file mode 100644 index 0000000000..86b9e7a5a4 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00028.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00029.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00029.png new file mode 100644 index 0000000000..4e1e94c543 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00029.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00030.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00030.png new file mode 100644 index 0000000000..35c4c10e0e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00030.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00031.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00031.png new file mode 100644 index 0000000000..a488c1d06a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00031.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00032.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00032.png new file mode 100644 index 0000000000..9a6a09c058 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00032.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00033.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00033.png new file mode 100644 index 0000000000..5ef54ebef8 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00033.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00034.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00034.png new file mode 100644 index 0000000000..777fc7755c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00034.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00035.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00035.png new file mode 100644 index 0000000000..510179f739 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00035.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00036.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00036.png new file mode 100644 index 0000000000..44a13f1177 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00036.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00037.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00037.png new file mode 100644 index 0000000000..adf2e1717b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00037.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00038.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00038.png new file mode 100644 index 0000000000..c68cd1c83f Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00038.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00039.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00039.png new file mode 100644 index 0000000000..2e94ac7513 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00039.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00040.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00040.png new file mode 100644 index 0000000000..78ab332d50 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00040.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00041.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00041.png new file mode 100644 index 0000000000..5f0fe2ea90 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00041.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00042.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00042.png new file mode 100644 index 0000000000..4ff5603fde Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00042.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00043.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00043.png new file mode 100644 index 0000000000..5d16230d11 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00043.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00044.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00044.png new file mode 100644 index 0000000000..ad98992dcd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00044.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00045.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00045.png new file mode 100644 index 0000000000..d215c6babe Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00045.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00046.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00046.png new file mode 100644 index 0000000000..7faace9e41 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00046.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00047.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00047.png new file mode 100644 index 0000000000..7765304e6c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00047.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00048.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00048.png new file mode 100644 index 0000000000..7bd0d2594c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00048.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00049.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00049.png new file mode 100644 index 0000000000..9a2b57abb0 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00049.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00050.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00050.png new file mode 100644 index 0000000000..fc388fd2cd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00050.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00051.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00051.png new file mode 100644 index 0000000000..70aeca0e4e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00051.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00052.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00052.png new file mode 100644 index 0000000000..23394fefbc Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00052.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00053.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00053.png new file mode 100644 index 0000000000..06b0bcc1f7 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00053.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00054.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00054.png new file mode 100644 index 0000000000..d1dff8a80c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00054.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00055.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00055.png new file mode 100644 index 0000000000..e641353fe3 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00055.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00056.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00056.png new file mode 100644 index 0000000000..4a426b4469 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00056.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00057.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00057.png new file mode 100644 index 0000000000..73f1d021da Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00057.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00058.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00058.png new file mode 100644 index 0000000000..ac72979993 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00058.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00059.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00059.png new file mode 100644 index 0000000000..1ac5a3944a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00059.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00060.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00060.png new file mode 100644 index 0000000000..26fbfaf98a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00060.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00061.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00061.png new file mode 100644 index 0000000000..5f1ed4104d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00061.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00062.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00062.png new file mode 100644 index 0000000000..16d996c047 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00062.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00063.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00063.png new file mode 100644 index 0000000000..6bd058a870 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00063.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00064.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00064.png new file mode 100644 index 0000000000..cfc1f795fe Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00064.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00065.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00065.png new file mode 100644 index 0000000000..6b01b8465d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00065.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00066.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00066.png new file mode 100644 index 0000000000..bdafd42c89 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00066.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00067.png b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00067.png new file mode 100644 index 0000000000..0a0eb347b4 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-ldpi/mogo_tts_icon_00067.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/ic_kuwo.webp b/modules/mogo-module-apps/src/main/res/drawable-mdpi/ic_kuwo.webp new file mode 100644 index 0000000000..82330db5fa Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/ic_kuwo.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_apps.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_apps.png new file mode 100644 index 0000000000..a56017fd57 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_apps.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_aux.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_aux.png new file mode 100644 index 0000000000..425894b2c0 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_aux.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_bt.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_bt.png new file mode 100644 index 0000000000..595b087455 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_bt.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_bt_phone.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_bt_phone.png new file mode 100644 index 0000000000..65b23ed5dd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_bt_phone.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_canbus.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_canbus.png new file mode 100644 index 0000000000..f29ce31281 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_canbus.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_car_setting.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_car_setting.png new file mode 100644 index 0000000000..3f8c6f8483 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_car_setting.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_car_settings.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_car_settings.png new file mode 100644 index 0000000000..cd4253095b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_car_settings.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_carcorder.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_carcorder.png new file mode 100644 index 0000000000..076e301e62 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_carcorder.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_chat.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_chat.png new file mode 100644 index 0000000000..d099b857d9 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_chat.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_chat_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_chat_unchecked.png new file mode 100644 index 0000000000..d76595c392 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_chat_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_clean_master.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_clean_master.png new file mode 100644 index 0000000000..594b36fa2e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_clean_master.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_default_icon.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_default_icon.png new file mode 100644 index 0000000000..898f3ed59a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_default_icon.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_equlizer.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_equlizer.png new file mode 100644 index 0000000000..d9e94aa25b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_equlizer.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fleet.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fleet.png new file mode 100644 index 0000000000..f9a9cb0b91 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fleet.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fm.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fm.png new file mode 100644 index 0000000000..bfec997202 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fm.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fota.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fota.png new file mode 100644 index 0000000000..1eb98da08b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fota.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fresh_things.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fresh_things.png new file mode 100644 index 0000000000..41ec3ad07d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_fresh_things.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_icon_map.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_icon_map.png new file mode 100644 index 0000000000..a4f8d3f16e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_icon_map.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_im.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_im.png new file mode 100644 index 0000000000..9a08151023 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_im.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_interest.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_interest.png new file mode 100644 index 0000000000..d2fac8cf3a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_interest.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_interest_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_interest_unchecked.png new file mode 100644 index 0000000000..c7d89c68ad Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_interest_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_local_video.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_local_video.png new file mode 100644 index 0000000000..813c00b262 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_local_video.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_lrts.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_lrts.png new file mode 100644 index 0000000000..b8b9cc814b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_lrts.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_media_center.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_media_center.png new file mode 100644 index 0000000000..044ceb0683 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_media_center.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_media_center_checked.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_media_center_checked.png new file mode 100644 index 0000000000..fa1b977bfa Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_media_center_checked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigation.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigation.png new file mode 100644 index 0000000000..f192abed11 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigation.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_applist.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_applist.png new file mode 100644 index 0000000000..f884758d3d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_applist.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_im.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_im.png new file mode 100644 index 0000000000..7a959f1ca1 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_im.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_media.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_media.png new file mode 100644 index 0000000000..d9f6df313d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_media.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_navi.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_navi.png new file mode 100644 index 0000000000..2401ce7c2a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_navi.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_navi_disable.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_navi_disable.png new file mode 100644 index 0000000000..3df9f14026 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_navigator_navi_disable.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_news.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_news.png new file mode 100644 index 0000000000..c86bcef363 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_news.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_news_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_news_unchecked.png new file mode 100644 index 0000000000..77343ff931 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_news_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_online_car.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_online_car.png new file mode 100644 index 0000000000..9922237c77 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_online_car.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_online_car_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_online_car_unchecked.png new file mode 100644 index 0000000000..318e9535a0 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_online_car_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_personal_center.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_personal_center.png new file mode 100644 index 0000000000..14f9134a80 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_personal_center.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_qiyi.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_qiyi.png new file mode 100644 index 0000000000..1d885be37f Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_qiyi.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_qq_music.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_qq_music.png new file mode 100644 index 0000000000..dea1154a13 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_qq_music.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_retract.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_retract.png new file mode 100644 index 0000000000..24d42281c4 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_retract.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_road_condition.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_road_condition.png new file mode 100644 index 0000000000..12c5d954b8 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_road_condition.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_stee_product.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_stee_product.png new file mode 100644 index 0000000000..e3040f195f Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_stee_product.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_tanlu.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_tanlu.png new file mode 100644 index 0000000000..32afef191d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_tanlu.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_tanlu_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_tanlu_unchecked.png new file mode 100644 index 0000000000..4b451a1178 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_tanlu_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_we_car_flow.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_we_car_flow.png new file mode 100644 index 0000000000..95734bb594 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_we_car_flow.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_wechat.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_wechat.png new file mode 100644 index 0000000000..136b3e6ab8 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_wechat.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_welfare.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_welfare.png new file mode 100644 index 0000000000..dc951e6133 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_welfare.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_ximalaya.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_ximalaya.png new file mode 100644 index 0000000000..9c55842f45 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/module_apps_ic_ximalaya.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00000.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00000.png new file mode 100644 index 0000000000..fb93d34e52 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00000.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00001.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00001.png new file mode 100644 index 0000000000..2d90014c88 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00001.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00002.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00002.png new file mode 100644 index 0000000000..cebabd17dd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00002.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00003.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00003.png new file mode 100644 index 0000000000..7de16583b3 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00003.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00004.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00004.png new file mode 100644 index 0000000000..889e1fda6a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00004.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00005.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00005.png new file mode 100644 index 0000000000..af4a3d909c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00005.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00006.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00006.png new file mode 100644 index 0000000000..0c30ddd100 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00006.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00007.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00007.png new file mode 100644 index 0000000000..c22e60f799 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00007.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00008.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00008.png new file mode 100644 index 0000000000..5fdd402211 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00008.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00009.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00009.png new file mode 100644 index 0000000000..59a89a6a49 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00009.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00010.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00010.png new file mode 100644 index 0000000000..fd41cd22e5 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00010.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00011.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00011.png new file mode 100644 index 0000000000..feccc9606d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00011.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00012.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00012.png new file mode 100644 index 0000000000..0c8586d2d4 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00012.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00013.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00013.png new file mode 100644 index 0000000000..00d78703cd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00013.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00014.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00014.png new file mode 100644 index 0000000000..a0dae668ff Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00014.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00015.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00015.png new file mode 100644 index 0000000000..d5c4162e35 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00015.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00016.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00016.png new file mode 100644 index 0000000000..9b942cde66 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00016.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00017.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00017.png new file mode 100644 index 0000000000..e2e429f2ad Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00017.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00018.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00018.png new file mode 100644 index 0000000000..058e5dbf6e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00018.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00019.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00019.png new file mode 100644 index 0000000000..e992640008 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00019.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00020.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00020.png new file mode 100644 index 0000000000..974e26deca Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00020.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00021.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00021.png new file mode 100644 index 0000000000..0582f43235 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00021.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00022.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00022.png new file mode 100644 index 0000000000..3460520479 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00022.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00023.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00023.png new file mode 100644 index 0000000000..0816cb4016 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00023.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00024.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00024.png new file mode 100644 index 0000000000..0a42e16b7e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00024.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00025.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00025.png new file mode 100644 index 0000000000..592137d15f Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00025.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00026.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00026.png new file mode 100644 index 0000000000..25d14c902b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00026.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00027.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00027.png new file mode 100644 index 0000000000..ec90bcf254 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00027.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00028.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00028.png new file mode 100644 index 0000000000..86b9e7a5a4 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00028.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00029.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00029.png new file mode 100644 index 0000000000..4e1e94c543 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00029.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00030.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00030.png new file mode 100644 index 0000000000..35c4c10e0e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00030.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00031.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00031.png new file mode 100644 index 0000000000..a488c1d06a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00031.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00032.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00032.png new file mode 100644 index 0000000000..9a6a09c058 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00032.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00033.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00033.png new file mode 100644 index 0000000000..5ef54ebef8 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00033.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00034.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00034.png new file mode 100644 index 0000000000..777fc7755c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00034.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00035.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00035.png new file mode 100644 index 0000000000..510179f739 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00035.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00036.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00036.png new file mode 100644 index 0000000000..44a13f1177 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00036.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00037.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00037.png new file mode 100644 index 0000000000..adf2e1717b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00037.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00038.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00038.png new file mode 100644 index 0000000000..c68cd1c83f Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00038.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00039.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00039.png new file mode 100644 index 0000000000..2e94ac7513 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00039.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00040.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00040.png new file mode 100644 index 0000000000..78ab332d50 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00040.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00041.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00041.png new file mode 100644 index 0000000000..5f0fe2ea90 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00041.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00042.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00042.png new file mode 100644 index 0000000000..4ff5603fde Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00042.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00043.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00043.png new file mode 100644 index 0000000000..5d16230d11 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00043.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00044.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00044.png new file mode 100644 index 0000000000..ad98992dcd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00044.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00045.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00045.png new file mode 100644 index 0000000000..d215c6babe Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00045.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00046.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00046.png new file mode 100644 index 0000000000..7faace9e41 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00046.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00047.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00047.png new file mode 100644 index 0000000000..7765304e6c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00047.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00048.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00048.png new file mode 100644 index 0000000000..7bd0d2594c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00048.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00049.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00049.png new file mode 100644 index 0000000000..9a2b57abb0 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00049.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00050.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00050.png new file mode 100644 index 0000000000..fc388fd2cd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00050.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00051.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00051.png new file mode 100644 index 0000000000..70aeca0e4e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00051.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00052.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00052.png new file mode 100644 index 0000000000..23394fefbc Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00052.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00053.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00053.png new file mode 100644 index 0000000000..06b0bcc1f7 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00053.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00054.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00054.png new file mode 100644 index 0000000000..d1dff8a80c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00054.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00055.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00055.png new file mode 100644 index 0000000000..e641353fe3 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00055.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00056.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00056.png new file mode 100644 index 0000000000..4a426b4469 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00056.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00057.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00057.png new file mode 100644 index 0000000000..73f1d021da Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00057.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00058.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00058.png new file mode 100644 index 0000000000..ac72979993 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00058.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00059.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00059.png new file mode 100644 index 0000000000..1ac5a3944a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00059.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00060.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00060.png new file mode 100644 index 0000000000..26fbfaf98a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00060.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00061.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00061.png new file mode 100644 index 0000000000..5f1ed4104d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00061.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00062.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00062.png new file mode 100644 index 0000000000..16d996c047 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00062.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00063.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00063.png new file mode 100644 index 0000000000..6bd058a870 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00063.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00064.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00064.png new file mode 100644 index 0000000000..cfc1f795fe Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00064.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00065.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00065.png new file mode 100644 index 0000000000..6b01b8465d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00065.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00066.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00066.png new file mode 100644 index 0000000000..bdafd42c89 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00066.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00067.png b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00067.png new file mode 100644 index 0000000000..0a0eb347b4 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-mdpi/mogo_tts_icon_00067.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_ai_assist.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_ai_assist.webp new file mode 100644 index 0000000000..32392f303e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_ai_assist.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_ai_assist_bkg.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_ai_assist_bkg.png new file mode 100644 index 0000000000..e86c3454df Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_ai_assist_bkg.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_apps.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_apps.png new file mode 100755 index 0000000000..f1fc6671f2 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_apps.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_auto_navi.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_auto_navi.png new file mode 100644 index 0000000000..acf89ddcf8 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_auto_navi.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_aux.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_aux.webp new file mode 100644 index 0000000000..80c50e4172 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_aux.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_bt.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_bt.webp new file mode 100644 index 0000000000..7007b6b849 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_bt.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_bt_music.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_bt_music.webp new file mode 100644 index 0000000000..6778d03293 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_bt_music.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_bt_phone.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_bt_phone.webp new file mode 100644 index 0000000000..210f7ab524 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_bt_phone.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_canbus.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_canbus.webp new file mode 100644 index 0000000000..f7ffe16471 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_canbus.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_car_setting.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_car_setting.webp new file mode 100644 index 0000000000..104dda808f Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_car_setting.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_car_settings.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_car_settings.webp new file mode 100644 index 0000000000..64ac80ec89 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_car_settings.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_carcorder.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_carcorder.webp new file mode 100644 index 0000000000..cb9baebbac Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_carcorder.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_chat.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_chat.webp new file mode 100644 index 0000000000..6217103ade Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_chat.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_chat_icon.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_chat_icon.png new file mode 100755 index 0000000000..9d74b24ea8 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_chat_icon.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_chat_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_chat_unchecked.png new file mode 100755 index 0000000000..9b4d5501dc Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_chat_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_clean_master.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_clean_master.webp new file mode 100644 index 0000000000..ede7031fbd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_clean_master.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_default_icon.png similarity index 100% rename from app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_default_icon.png diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_equlizer.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_equlizer.png new file mode 100755 index 0000000000..538b3111fd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_equlizer.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fleet.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fleet.webp new file mode 100644 index 0000000000..e55dceca76 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fleet.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fm.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fm.png new file mode 100755 index 0000000000..a60cb64208 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fm.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fota.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fota.png new file mode 100755 index 0000000000..f0cb755032 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fota.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fresh_things.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fresh_things.webp new file mode 100644 index 0000000000..b9b058a124 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_fresh_things.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_icon_map.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_icon_map.png new file mode 100755 index 0000000000..fcda460264 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_icon_map.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_im.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_im.webp new file mode 100644 index 0000000000..5a7081f4e7 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_im.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_interest.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_interest.png new file mode 100755 index 0000000000..5d0d4e1a6d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_interest.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_interest_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_interest_unchecked.png new file mode 100755 index 0000000000..807d603b7b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_interest_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_local_music.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_local_music.png new file mode 100644 index 0000000000..5b1ec9b795 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_local_music.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_local_video.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_local_video.png new file mode 100644 index 0000000000..e7086c667d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_local_video.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_lrts.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_lrts.png new file mode 100755 index 0000000000..77e3c31a55 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_lrts.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_media_center.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_media_center.png new file mode 100755 index 0000000000..1e6247d47a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_media_center.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_media_center_checked.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_media_center_checked.png new file mode 100755 index 0000000000..ded21b6af2 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_media_center_checked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_music.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_music.png new file mode 100755 index 0000000000..8f5b1de38e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_music.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigation.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigation.png new file mode 100755 index 0000000000..624484956b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigation.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_applist.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_applist.png new file mode 100755 index 0000000000..b95bc4576f Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_applist.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_im.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_im.png new file mode 100755 index 0000000000..3ee3703675 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_im.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_media.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_media.png new file mode 100755 index 0000000000..bcfdb9cfa9 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_media.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_navi.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_navi.png new file mode 100755 index 0000000000..deee86ed15 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_navi.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_navi_disable.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_navi_disable.png new file mode 100644 index 0000000000..6a00c94c9d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_navigator_navi_disable.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_news.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_news.png new file mode 100755 index 0000000000..b3bc19464e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_news.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_news_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_news_unchecked.png new file mode 100755 index 0000000000..5a64a68660 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_news_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_online_car.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_online_car.png new file mode 100755 index 0000000000..761a11b72a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_online_car.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_online_car_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_online_car_unchecked.png new file mode 100755 index 0000000000..b967fc7071 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_online_car_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_personal_center.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_personal_center.webp new file mode 100644 index 0000000000..af0a6f12ec Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_personal_center.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_qiyi.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_qiyi.png new file mode 100755 index 0000000000..8ce12c8f73 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_qiyi.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_qq_music.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_qq_music.png new file mode 100755 index 0000000000..a67563b193 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_qq_music.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_retract.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_retract.png new file mode 100755 index 0000000000..8c37a69e35 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_retract.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_road_condition.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_road_condition.webp new file mode 100644 index 0000000000..3ee10f5b5d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_road_condition.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_stee_product.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_stee_product.png new file mode 100755 index 0000000000..52d187838d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_stee_product.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_tanlu.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_tanlu.png new file mode 100755 index 0000000000..edd6eaca26 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_tanlu.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_tanlu_unchecked.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_tanlu_unchecked.png new file mode 100755 index 0000000000..ac2a05136b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_tanlu_unchecked.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_weather.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_weather.webp new file mode 100644 index 0000000000..5d534a5198 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_weather.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_wechat.webp b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_wechat.webp new file mode 100644 index 0000000000..97af1fc366 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_wechat.webp differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_welfare.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_welfare.png new file mode 100755 index 0000000000..adb740db77 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_welfare.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_ximalaya.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_ximalaya.png new file mode 100755 index 0000000000..1252187fbd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/module_apps_ic_ximalaya.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00000.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00000.png new file mode 100644 index 0000000000..cf76dec7ee Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00000.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00001.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00001.png new file mode 100644 index 0000000000..759b133363 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00001.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00002.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00002.png new file mode 100644 index 0000000000..2acc31fd75 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00002.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00003.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00003.png new file mode 100644 index 0000000000..fcd2de6ab0 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00003.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00004.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00004.png new file mode 100644 index 0000000000..0185747f28 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00004.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00005.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00005.png new file mode 100644 index 0000000000..133e230955 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00005.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00006.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00006.png new file mode 100644 index 0000000000..01a2614deb Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00006.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00007.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00007.png new file mode 100644 index 0000000000..21b59f46d2 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00007.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00008.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00008.png new file mode 100644 index 0000000000..c0fb4687d6 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00008.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00009.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00009.png new file mode 100644 index 0000000000..636d45d153 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00009.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00010.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00010.png new file mode 100644 index 0000000000..4c84c50a6a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00010.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00011.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00011.png new file mode 100644 index 0000000000..27c7cd20ca Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00011.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00012.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00012.png new file mode 100644 index 0000000000..a7ccf5f35f Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00012.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00013.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00013.png new file mode 100644 index 0000000000..a2d6aec518 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00013.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00014.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00014.png new file mode 100644 index 0000000000..65ead253fb Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00014.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00015.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00015.png new file mode 100644 index 0000000000..4a565bdcb2 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00015.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00016.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00016.png new file mode 100644 index 0000000000..a752fa5f60 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00016.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00017.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00017.png new file mode 100644 index 0000000000..0c089db1a0 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00017.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00018.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00018.png new file mode 100644 index 0000000000..496de625bd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00018.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00019.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00019.png new file mode 100644 index 0000000000..a805ad75aa Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00019.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00020.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00020.png new file mode 100644 index 0000000000..656ab722d4 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00020.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00021.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00021.png new file mode 100644 index 0000000000..73e02f07b1 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00021.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00022.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00022.png new file mode 100644 index 0000000000..04fd01e5a9 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00022.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00023.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00023.png new file mode 100644 index 0000000000..2b42ab31ec Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00023.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00024.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00024.png new file mode 100644 index 0000000000..f25ca2c8e8 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00024.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00025.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00025.png new file mode 100644 index 0000000000..2cb7d768da Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00025.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00026.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00026.png new file mode 100644 index 0000000000..a30ed348b5 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00026.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00027.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00027.png new file mode 100644 index 0000000000..37977fdbcd Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00027.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00028.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00028.png new file mode 100644 index 0000000000..c461373d86 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00028.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00029.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00029.png new file mode 100644 index 0000000000..6eb46799ee Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00029.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00030.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00030.png new file mode 100644 index 0000000000..c874c287ae Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00030.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00031.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00031.png new file mode 100644 index 0000000000..fd1ee80c15 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00031.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00032.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00032.png new file mode 100644 index 0000000000..f89fdb368d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00032.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00033.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00033.png new file mode 100644 index 0000000000..d199137e5b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00033.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00034.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00034.png new file mode 100644 index 0000000000..5e612da15b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00034.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00035.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00035.png new file mode 100644 index 0000000000..bf394dbcd3 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00035.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00036.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00036.png new file mode 100644 index 0000000000..ca5ad37df8 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00036.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00037.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00037.png new file mode 100644 index 0000000000..76bc2391e8 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00037.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00038.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00038.png new file mode 100644 index 0000000000..d9a2049f96 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00038.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00039.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00039.png new file mode 100644 index 0000000000..3a46da466e Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00039.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00040.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00040.png new file mode 100644 index 0000000000..f89b0d748c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00040.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00041.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00041.png new file mode 100644 index 0000000000..41ba5ebe7b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00041.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00042.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00042.png new file mode 100644 index 0000000000..a99b80df64 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00042.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00043.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00043.png new file mode 100644 index 0000000000..75cbaec133 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00043.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00044.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00044.png new file mode 100644 index 0000000000..95caadf725 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00044.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00045.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00045.png new file mode 100644 index 0000000000..935cb08383 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00045.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00046.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00046.png new file mode 100644 index 0000000000..54ad3719dc Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00046.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00047.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00047.png new file mode 100644 index 0000000000..e7c4c6dd7d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00047.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00048.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00048.png new file mode 100644 index 0000000000..358b8b442b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00048.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00049.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00049.png new file mode 100644 index 0000000000..83c7946a1d Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00049.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00050.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00050.png new file mode 100644 index 0000000000..ff7a6cfbaa Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00050.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00051.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00051.png new file mode 100644 index 0000000000..52c81af36b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00051.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00052.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00052.png new file mode 100644 index 0000000000..6c22bb0827 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00052.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00053.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00053.png new file mode 100644 index 0000000000..df233a72ab Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00053.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00054.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00054.png new file mode 100644 index 0000000000..ee9eaf6588 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00054.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00055.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00055.png new file mode 100644 index 0000000000..f3f6bfdfe3 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00055.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00056.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00056.png new file mode 100644 index 0000000000..a4460ef16c Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00056.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00057.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00057.png new file mode 100644 index 0000000000..23e1fa00b6 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00057.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00058.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00058.png new file mode 100644 index 0000000000..1331514201 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00058.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00059.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00059.png new file mode 100644 index 0000000000..a897f3750b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00059.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00060.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00060.png new file mode 100644 index 0000000000..ab92e11b21 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00060.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00061.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00061.png new file mode 100644 index 0000000000..aa8a1a7628 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00061.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00062.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00062.png new file mode 100644 index 0000000000..0aad924d12 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00062.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00063.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00063.png new file mode 100644 index 0000000000..a166e7fe19 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00063.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00064.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00064.png new file mode 100644 index 0000000000..46a47ead66 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00064.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00065.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00065.png new file mode 100644 index 0000000000..52c9430792 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00065.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00066.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00066.png new file mode 100644 index 0000000000..04d556923b Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00066.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00067.png b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00067.png new file mode 100644 index 0000000000..b7dab9a929 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable-xhdpi/mogo_tts_icon_00067.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_auto_navi.png b/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_auto_navi.png new file mode 100644 index 0000000000..6608281c32 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_auto_navi.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_bt_music.png b/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_bt_music.png new file mode 100644 index 0000000000..ab2049675a Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_bt_music.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_local_music.png b/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_local_music.png new file mode 100644 index 0000000000..bc3f813916 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_local_music.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_weather.png b/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_weather.png new file mode 100644 index 0000000000..5c4d7eea82 Binary files /dev/null and b/modules/mogo-module-apps/src/main/res/drawable/module_apps_ic_weather.png differ diff --git a/modules/mogo-module-apps/src/main/res/drawable/module_apps_pager_indicator.xml b/modules/mogo-module-apps/src/main/res/drawable/module_apps_pager_indicator.xml new file mode 100644 index 0000000000..1a2fabf863 --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/drawable/module_apps_pager_indicator.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/mogo-module-apps/src/main/res/drawable/module_apps_pager_sliding_background_tab.xml b/modules/mogo-module-apps/src/main/res/drawable/module_apps_pager_sliding_background_tab.xml new file mode 100644 index 0000000000..f37210ee5f --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/drawable/module_apps_pager_sliding_background_tab.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/drawable/module_apps_shape_deep_blue.xml b/modules/mogo-module-apps/src/main/res/drawable/module_apps_shape_deep_blue.xml new file mode 100644 index 0000000000..7ff2e3423a --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/drawable/module_apps_shape_deep_blue.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/layout/module_apps_activity_list.xml b/modules/mogo-module-apps/src/main/res/layout/module_apps_activity_list.xml new file mode 100644 index 0000000000..ae0d010c27 --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/layout/module_apps_activity_list.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/layout/module_apps_fragment_apps.xml b/modules/mogo-module-apps/src/main/res/layout/module_apps_fragment_apps.xml new file mode 100644 index 0000000000..4218f100d9 --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/layout/module_apps_fragment_apps.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/layout/module_apps_fragment_apps_navigator.xml b/modules/mogo-module-apps/src/main/res/layout/module_apps_fragment_apps_navigator.xml new file mode 100644 index 0000000000..ea8e2d1cc6 --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/layout/module_apps_fragment_apps_navigator.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/layout/module_apps_item_app.xml b/modules/mogo-module-apps/src/main/res/layout/module_apps_item_app.xml new file mode 100644 index 0000000000..49c0dd467e --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/layout/module_apps_item_app.xml @@ -0,0 +1,25 @@ + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/layout/module_apps_item_app_indicator.xml b/modules/mogo-module-apps/src/main/res/layout/module_apps_item_app_indicator.xml new file mode 100644 index 0000000000..3e6c2c2668 --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/layout/module_apps_item_app_indicator.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/layout/module_apps_item_app_pager.xml b/modules/mogo-module-apps/src/main/res/layout/module_apps_item_app_pager.xml new file mode 100644 index 0000000000..b7fce405bf --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/layout/module_apps_item_app_pager.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/layout/module_apps_page_indicator.xml b/modules/mogo-module-apps/src/main/res/layout/module_apps_page_indicator.xml new file mode 100644 index 0000000000..48ee3ce82b --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/layout/module_apps_page_indicator.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/values-xhdpi/dimens.xml b/modules/mogo-module-apps/src/main/res/values-xhdpi/dimens.xml new file mode 100644 index 0000000000..a9ba5a2fef --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/values-xhdpi/dimens.xml @@ -0,0 +1,29 @@ + + + 160px + 5px + 30px + 4px + 103px + 180px + @dimen/module_apps_navigation_icon_width + 43px + 60px + 32px + 37.5px + 180px + 180px + 136px + 174px + 523px + 18px + 35px + 94px + 94px + + 140px + 140px + 30px + 100px + 100px + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/values/colors.xml b/modules/mogo-module-apps/src/main/res/values/colors.xml new file mode 100644 index 0000000000..6fb34a3513 --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/values/colors.xml @@ -0,0 +1,20 @@ + + + #008577 + #00574B + #D81B60 + #ff080625 + #FFFFFF + #00000000 + #1AFFFFFF + #99FFFFFF + #CCFFFFFF + #7FFFFFFF + #00BFFF + #4DFFFFFF + #4D080625 + + #080625 + #3E7FFC + + diff --git a/modules/mogo-module-apps/src/main/res/values/dimens.xml b/modules/mogo-module-apps/src/main/res/values/dimens.xml new file mode 100644 index 0000000000..679816b821 --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/values/dimens.xml @@ -0,0 +1,29 @@ + + + 85px + 2.7px + 16px + 2.3px + 54.9px + 96px + @dimen/module_apps_navigation_icon_width + 22px + 33px + 24px + 20px + 96px + 96px + 279px + 88px + 95px + 9.5px + 18px + 50px + 50px + + 78px + 78px + 17px + 60px + 60px + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/values/psts_attrs_v2.xml b/modules/mogo-module-apps/src/main/res/values/psts_attrs_v2.xml new file mode 100644 index 0000000000..5af7a74dac --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/values/psts_attrs_v2.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-apps/src/main/res/values/strings.xml b/modules/mogo-module-apps/src/main/res/values/strings.xml new file mode 100644 index 0000000000..10a1675519 --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/values/strings.xml @@ -0,0 +1,46 @@ + + mogo-module-apps + APP 未安装 + 新手引导服务未加载 + 为了您的安全,导航中不可播放视频 + + com.mogo.launcher + com.mogo.launcher.app + com.zhidao.launcher + com.nwd.android.toolsmanager + com.nwd.filemanager + com.zhidao.autopilot + com.android.browser + com.android.providers.downloads.ui + com.zhidao.guide.lock + com.android.calculator2 + com.nwd.guidebookskin + com.iflytek.inputmethod.pad + com.nwd.tools.reboot + com.android.car.setting + com.zhidao.bootmanager + com.zhidao.services + com.android.settings + com.android.documentsui + com.android.messaging + com.android.contacts + com.android.dialer + + + com.mogo.launcher + com.mogo.launcher.app + com.zhidao.launcher + com.nwd.android.toolsmanager + com.nwd.filemanager + com.zhidao.autopilot + com.android.browser + com.android.settings + com.android.providers.downloads.ui + com.zhidao.guide.lock + com.android.calculator2 + com.nwd.guidebookskin + com.iflytek.inputmethod.pad + com.nwd.tools.reboot + com.android.car.setting + + diff --git a/modules/mogo-module-apps/src/main/res/values/styles.xml b/modules/mogo-module-apps/src/main/res/values/styles.xml new file mode 100644 index 0000000000..06dc431aec --- /dev/null +++ b/modules/mogo-module-apps/src/main/res/values/styles.xml @@ -0,0 +1,29 @@ + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-authorize/.gitignore b/modules/mogo-module-authorize/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/modules/mogo-module-authorize/.gitignore @@ -0,0 +1 @@ +/build diff --git a/modules/mogo-module-authorize/build.gradle b/modules/mogo-module-authorize/build.gradle new file mode 100644 index 0000000000..8f19f33858 --- /dev/null +++ b/modules/mogo-module-authorize/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-kapt' +apply plugin: 'com.alibaba.arouter' + +android { + compileSdkVersion rootProject.ext.android.compileSdkVersion + + defaultConfig { + minSdkVersion rootProject.ext.android.minSdkVersion + targetSdkVersion rootProject.ext.android.targetSdkVersion + versionCode Integer.valueOf(VERSION_CODE) + versionName getValueFromRootProperties("${project.name.replace("-", "_").toUpperCase()}_VERSION") + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + + //ARouter apt 参数 + kapt { + useBuildCache = false + arguments { + arg("AROUTER_MODULE_NAME",project.getName() ) + } + } + + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation rootProject.ext.dependencies.kotlinstdlibjdk7 + implementation rootProject.ext.dependencies.androidxccorektx + implementation rootProject.ext.dependencies.coroutinescore + implementation rootProject.ext.dependencies.coroutinesandroid + implementation rootProject.ext.dependencies.androidxappcompat + implementation rootProject.ext.dependencies.androidxconstraintlayout + implementation rootProject.ext.dependencies.arouter + kapt rootProject.ext.dependencies.aroutercompiler + + if (Boolean.valueOf(RELEASE)) { + implementation rootProject.ext.dependencies.mogoutils + implementation rootProject.ext.dependencies.mogocommons + implementation rootProject.ext.dependencies.mogoserviceapi + implementation rootProject.ext.dependencies.modulecommon + } else { + implementation project(":foudations:mogo-utils") + implementation project(":foudations:mogo-commons") + implementation project(':services:mogo-service-api') + implementation project(":modules:mogo-module-common") + } +} + +apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString() diff --git a/modules/mogo-module-authorize/consumer-rules.pro b/modules/mogo-module-authorize/consumer-rules.pro new file mode 100644 index 0000000000..5668c1b3ca --- /dev/null +++ b/modules/mogo-module-authorize/consumer-rules.pro @@ -0,0 +1,2 @@ +#-----AuthorizeModule----- +-keep class com.mogo.module.authorize.module.bean.**{*;} \ No newline at end of file diff --git a/modules/mogo-module-authorize/gradle.properties b/modules/mogo-module-authorize/gradle.properties new file mode 100644 index 0000000000..aff034b53f --- /dev/null +++ b/modules/mogo-module-authorize/gradle.properties @@ -0,0 +1,3 @@ +GROUP=com.mogo.module +POM_ARTIFACT_ID=module-authorize +VERSION_CODE=1 \ No newline at end of file diff --git a/modules/mogo-module-authorize/proguard-rules.pro b/modules/mogo-module-authorize/proguard-rules.pro new file mode 100644 index 0000000000..ff909a2e24 --- /dev/null +++ b/modules/mogo-module-authorize/proguard-rules.pro @@ -0,0 +1,24 @@ +# 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 + +#-----AuthorizeModule----- +-keep class com.mogo.module.authorize.module.bean.**{*;} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/androidTest/java/com/mogo/module/authorize/ExampleInstrumentedTest.kt b/modules/mogo-module-authorize/src/androidTest/java/com/mogo/module/authorize/ExampleInstrumentedTest.kt new file mode 100644 index 0000000000..d5b381bd09 --- /dev/null +++ b/modules/mogo-module-authorize/src/androidTest/java/com/mogo/module/authorize/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.mogo.module.authorize + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.mogo.module.authorize.test", appContext.packageName) + } +} diff --git a/modules/mogo-module-authorize/src/main/AndroidManifest.xml b/modules/mogo-module-authorize/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..bdcca1cd30 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/IMogoAuthorizeController.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/IMogoAuthorizeController.kt new file mode 100644 index 0000000000..5e2ad53c7d --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/IMogoAuthorizeController.kt @@ -0,0 +1,140 @@ +package com.mogo.module.authorize.authprovider.biz + +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeContentListener +import com.mogo.module.authorize.model.BaseResponse +import com.mogo.module.authorize.model.IMogoAuthorizeModel +import com.mogo.module.authorize.model.bean.* +import com.mogo.module.authorize.net.request +import com.mogo.module.authorize.util.DateUtil.parseDateToTime +import com.mogo.module.authorize.util.SharedPreferenceUtil.getAuthorizeVersion +import com.mogo.module.authorize.util.SharedPreferenceUtil.setAuthorizeStatus +import com.mogo.module.authorize.util.SharedPreferenceUtil.updateAuthorizeVersion +import com.mogo.utils.logger.Logger + +open class IMogoAuthorizeController { + + companion object { + const val TAG = "AuthorizeController" + } + + private val authorizeModel: IMogoAuthorizeModel by lazy { IMogoAuthorizeModel() } + + fun getAuthorizeContent(onStart: () -> Unit, onSuccess: (Agreement) -> Unit, onError: (String) -> Unit) { + realInvokeAuthorizeContent(0, { + onStart.invoke() + }, { + if (it.result != null && it.result.agreement.agreementContent != null) { + onSuccess.invoke(it.result.agreement) + } else { + onError.invoke("data is null") + } + }, { msg: String -> + onError.invoke(msg) + }, true) + } + + fun invokeAuthorizeContent(tag: String, agreementType: Int) { + realInvokeAuthorizeContent(agreementType, { + if (agreementType == -1) { + getAuthorizeContentListener(tag, { listener -> + listener.requestContentFailed("invokeAuthorizeContent param tag is not right") + }, { + Logger.d(TAG, "invokeAuthorizeContent ---checkAgreementType can not find tag :$tag") + }) + } + }, { + getAuthorizeContentListener(tag, { listener -> + if (it.result != null && it.result.agreement.agreementContent != null) { + listener.requestContentSuccess(it.result.agreement) + } else { + listener.requestContentFailed("request authorize content success ,but result data is :${it.result}") + } + }, { + Logger.d(TAG, "invokeAuthorizeContent --- can not find listener by this tag :$tag") + }) + }, { msg: String -> + getAuthorizeContentListener(tag, { listener -> + listener.requestContentFailed(msg) + }, { + Logger.d(TAG, "invokeAuthorizeContent --- can not find listener by this tag :$tag") + }) + }) + } + + private fun realInvokeAuthorizeContent(agreementType: Int, onStart: (() -> Unit), onSuccess: ((BaseResponse) -> Unit), onError: ((String) -> Unit), needContent: Boolean = false) { + onStart.invoke() + try { + request> { + loader { + authorizeModel.invokeAuthorizeContent(agreementType, needContent) + } + onSuccess { + onSuccess.invoke(it) + } + onError { + onError.invoke(it.message + ?: "realInvokeAuthorizeContent onError, message is null") + } + } + } catch (e: Exception) { + e.printStackTrace() + onError.invoke(e.message ?: "realInvokeAuthorizeContent has exception, message is null") + } + } + + private inline fun getAuthorizeContentListener(tag: String, blockSuccess: ((IMogoAuthorizeContentListener) -> Unit), blockNull: (() -> Unit)) { + val authorizeContentListener = MogoAuthorizeRegisterHandler.getAuthorizeContentListener(tag) + if (authorizeContentListener != null) { + blockSuccess(authorizeContentListener) + } else { + blockNull() + } + } + + fun updateAgreementVersion(agreementType: Int) { + realInvokeAuthorizeContent(agreementType, { + Logger.d(TAG, "ready to update agreement") + }, { + if (it.result != null) { + val agreement = it.result.agreement + val updateTime = agreement.tUserAgreementEntity.updateTime + val currentTime = parseDateToTime(updateTime) + if (hasNewVersion(currentTime)) { + updateAuthorizeVersion(currentTime) + setAuthorizeStatus(agreementType, false) + } else { + Logger.d(TAG, "no new version") + } + } + }, { s: String -> + Logger.d(TAG, "updateAgreementAndAuthorization reason:$s") + }) + } + + private fun hasNewVersion(currentTime: Long): Boolean { + val oldVersion = getAuthorizeVersion() + return currentTime > oldVersion + } + + fun checkIfNeedAuthorize(agreementType: Int) { + request> { + loader { + authorizeModel.invokeIfNeedAuthorize(agreementType) + } + onSuccess { + Logger.d(TAG,"result : ${it.result}") + val result = it.result + when (result.agreementStatus) { + AGREEMENT_EFFECT -> setAuthorizeStatus(agreementType, true) + AGREEMENT_NOT_EFFECT -> setAuthorizeStatus(agreementType, false) + else -> Logger.d(TAG, "agreementStatus is not match any case") + } + } + onError { + //todo + Logger.d(TAG, it.message ?: "checkIfNeedAuthorize onError, message is null") + setAuthorizeStatus(agreementType, true) + } + } + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/MogoAuthorizeManagerImpl.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/MogoAuthorizeManagerImpl.kt new file mode 100644 index 0000000000..6c91ab12fc --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/MogoAuthorizeManagerImpl.kt @@ -0,0 +1,54 @@ +package com.mogo.module.authorize.authprovider.biz + +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeContentListener +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeInvoke +import com.mogo.module.authorize.authprovider.module.IMogoAcquireAuthorizeListener +import com.mogo.module.authorize.model.proxy.AuthorizeProxy +import com.mogo.module.authorize.model.proxy.toAuthorizeType +import com.mogo.module.authorize.util.SharedPreferenceUtil.needAuthorization +import com.mogo.utils.logger.Logger + +open abstract class MogoAuthorizeManagerImpl : IMogoAuthorizeInvoke { + + companion object { + const val TAG = "AuthorizeManagerImpl" + } + + private val baseController: IMogoAuthorizeController by lazy { IMogoAuthorizeController() } + + override fun needAuthorize(tag: String): Boolean { + Logger.d(TAG, "===== needAuthorize update agreement in background") + baseController.checkIfNeedAuthorize(tag.toAuthorizeType()) + return needAuthorization(tag.toAuthorizeType()) + } + + override fun updateAuthorizeStatus(tag: String) { + baseController.checkIfNeedAuthorize(tag.toAuthorizeType()) + } + + override fun invokeAuthorizeContent(tag: String) { + //todo 后面动态代理统一处理校验问题 + Logger.d(TAG, "tag:$tag") + val agreementType = AuthorizeProxy.getAuthorizeType(tag) + Logger.d(TAG, "agreementType:$agreementType") + baseController.invokeAuthorizeContent(tag, agreementType) + } + + override fun registerInvokeAuthorizeContentListener(tag: String, listener: IMogoAuthorizeContentListener) { + MogoAuthorizeRegisterHandler.registerInvokeAuthorizeContentListener(tag, listener) + } + + override fun unregisterInvokeAuthorizeContentListener(tag: String) { + MogoAuthorizeRegisterHandler.unregisterInvokeAuthorizeContentListener(tag) + } + + override fun registerAuthorizeListener(tag: String, listener: IMogoAcquireAuthorizeListener) { + Logger.d(TAG, "registerAuthorize tag : $tag listener:$listener") + MogoAuthorizeRegisterHandler.registerAuthorizeListener(tag, listener) + } + + override fun unregisterAuthorizeListener(tag: String) { + MogoAuthorizeRegisterHandler.unregisterAuthorizeListener(tag) + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/MogoAuthorizeProvider.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/MogoAuthorizeProvider.kt new file mode 100644 index 0000000000..beac0c0246 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/MogoAuthorizeProvider.kt @@ -0,0 +1,94 @@ +package com.mogo.module.authorize.authprovider.biz + +import android.content.Context +import android.os.Bundle +import android.view.View +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.marker.IMogoMarkerClickListener +import com.mogo.map.navi.IMogoNaviListener +import com.mogo.module.authorize.authprovider.invoke.AuthorizeConstant.Companion.PATH_AGREEMENT_MODULE_NAME +import com.mogo.module.authorize.authprovider.invoke.AuthorizeInvokerConstant.Companion.AUTHORIZE_TYPE_LAUNCHER_MAIN +import com.mogo.module.authorize.authprovider.launcher.MogoMainAuthorize.Companion.mogoAuthShow +import com.mogo.service.MogoServicePaths +import com.mogo.service.auth.IMogoAuthManager +import com.mogo.service.module.IMogoModuleLifecycle +import com.mogo.utils.logger.Logger + +@Route(path = MogoServicePaths.PATH_AGREEMENT) +class MogoAuthorizeProvider : IMogoAuthManager { + + companion object { + const val TAG = "MogoAuthorizeProvider" + } + + private var mContext:Context? = null + + override fun createFragment(context: Context?, data: Bundle?): Fragment? { + return null + } + + override fun createView(context: Context?): View? { + return null + } + + override fun getModuleName(): String { + return PATH_AGREEMENT_MODULE_NAME + } + + override fun getCardLifecycle(): IMogoModuleLifecycle? { + return null + } + + override fun getMapListener(): IMogoMapListener? { + return null + } + + override fun getType(): Int { + return 0 + } + + override fun getNaviListener(): IMogoNaviListener? { + return null + } + + override fun getLocationListener(): IMogoLocationListener? { + return null + } + + override fun getMarkerClickListener(): IMogoMarkerClickListener? { + return null + } + + override fun showAuth(context: Context?) { + mContext = context + if (mogoAuthShow.needAuthorize(AUTHORIZE_TYPE_LAUNCHER_MAIN)) { + mogoAuthShow.invokeAuthorizeForShow(mContext!!) + } else { + //首次进入Launcher同步一下授权状态,防止由于用户清除数据造成首次加载还会出现授权状态不同步问题 + mogoAuthShow.updateAuthorizeStatus(AUTHORIZE_TYPE_LAUNCHER_MAIN) + Logger.d(TAG, "not do match self startUp condition ,wait for someone invoke") + } + } + + override fun dismiss() { + mogoAuthShow.hideAuthorizeView() + } + + override fun init(context: Context) { + //todo 引导判断暂时去掉 后续引导流程更改完再放开 +// todo if (isDeviceOfD() && hasGuide() && mogoAuthShow.needAuthorize(AUTHORIZE_TYPE_LAUNCHER_MAIN)) { + // todo F系列暂时没有授权功能 1.1需求中添加 全量上 + } + + override fun getAppPackage(): String? { + return null + } + + override fun getAppName(): String? { + return null + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/MogoAuthorizeRegisterHandler.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/MogoAuthorizeRegisterHandler.kt new file mode 100644 index 0000000000..889e0e70b2 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/biz/MogoAuthorizeRegisterHandler.kt @@ -0,0 +1,43 @@ +package com.mogo.module.authorize.authprovider.biz + +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeContentListener +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeRegister +import com.mogo.module.authorize.authprovider.module.IMogoAcquireAuthorizeListener +import com.mogo.utils.logger.Logger +import java.util.concurrent.ConcurrentHashMap + +object MogoAuthorizeRegisterHandler : IMogoAuthorizeRegister { + + private val authMap: ConcurrentHashMap = ConcurrentHashMap() + private val authContentMap: ConcurrentHashMap = ConcurrentHashMap() + + override fun registerAuthorizeListener(tag: String, listener: IMogoAcquireAuthorizeListener) { + Logger.d("RegisterHandler", "tag : $tag listener:$listener") + authMap[tag] = listener + } + + override fun unregisterAuthorizeListener(tag: String) { + authMap.remove(tag) + } + + fun getAuthorizeListener(tag: String): IMogoAcquireAuthorizeListener? { + return authMap[tag] + } + + fun getAllAuthorizeListener(): ConcurrentHashMap { + return authMap + } + + override fun registerInvokeAuthorizeContentListener(tag: String, listener: IMogoAuthorizeContentListener) { + authContentMap[tag] = listener + } + + override fun unregisterInvokeAuthorizeContentListener(tag: String) { + authContentMap.remove(tag) + } + + fun getAuthorizeContentListener(tag: String): IMogoAuthorizeContentListener? { + return authContentMap[tag] + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/AuthorizeConstant.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/AuthorizeConstant.kt new file mode 100644 index 0000000000..3da6930843 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/AuthorizeConstant.kt @@ -0,0 +1,14 @@ +package com.mogo.module.authorize.authprovider.invoke + +class AuthorizeConstant { + + companion object{ + const val PROVIDER_MODULE = "/authorize/biz" + const val PROVIDER_LAUNCHER = "/authorize/showbiz" + + /** + * provider模块实例名称(暂时仅有卡片用到) + */ + const val PATH_AGREEMENT_MODULE_NAME = "AGREEMENT_MODULE_NAME" + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/AuthorizeInvokerConstant.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/AuthorizeInvokerConstant.kt new file mode 100644 index 0000000000..af3930f91b --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/AuthorizeInvokerConstant.kt @@ -0,0 +1,15 @@ +package com.mogo.module.authorize.authprovider.invoke + +class AuthorizeInvokerConstant { + + companion object { + const val AUTHORIZE_TYPE_LAUNCHER_MAIN = "AUTHORIZE_TYPE_LAUNCHER_MAIN" //launcher + const val AUTHORIZE_TYPE_LAUNCHER_SHARE_NOVELTY = "AUTHORIZE_TYPE_LAUNCHER_SHARE_NOVELTY" //launcher 新鲜事分享 + const val AUTHORIZE_TYPE_LAUNCHER_SHARE_MUSIC = "AUTHORIZE_TYPE_LAUNCHER_SHARE_MUSIC" //launcher 音乐分享 + const val AUTHORIZE_TYPE_LAUNCHER_SHARE = "AUTHORIZE_TYPE_LAUNCHER_SHARE" //launcher 我要分享 + const val AUTHORIZE_TYPE_TAN_LU = "AUTHORIZE_TYPE_TAN_LU" //探路 + const val AUTHORIZE_TYPE_CALL_CHAT = "AUTHORIZE_TYPE_CALL_CHAT" //车聊聊 + const val AUTHORIZE_TYPE_NOVELTY = "AUTHORIZE_TYPE_NOVELTY" //新鲜事 + const val AUTHORIZE_TYPE_AUXILIARY_DRIVING = "AUTHORIZE_TYPE_AUXILIARY_DRIVING" //辅助驾驶 + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeContentListener.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeContentListener.kt new file mode 100644 index 0000000000..06a999aa3e --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeContentListener.kt @@ -0,0 +1,13 @@ +package com.mogo.module.authorize.authprovider.invoke + +import com.mogo.module.authorize.model.bean.Agreement + +/** + * 获取授权信息回调 + */ +interface IMogoAuthorizeContentListener { + + fun requestContentSuccess(userAgreement: Agreement) + + fun requestContentFailed(errorMsg: String) +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeForbiddenVoice.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeForbiddenVoice.kt new file mode 100644 index 0000000000..bc646e2024 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeForbiddenVoice.kt @@ -0,0 +1,9 @@ +package com.mogo.module.authorize.authprovider.invoke + +interface IMogoAuthorizeForbiddenVoice { + + /** + * 当授权页面展示时,语音回调不生效(唤醒、免唤醒) + */ + fun forbiddenVoiceWhenAuthorize(cmd: String) +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeInvoke.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeInvoke.kt new file mode 100644 index 0000000000..c84550a0b7 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeInvoke.kt @@ -0,0 +1,26 @@ +package com.mogo.module.authorize.authprovider.invoke + +/** + * 公共Business业务 + */ +interface IMogoAuthorizeInvoke : IMogoAuthorizeRegister { + + /** + * 是否需要授权 + */ + fun needAuthorize(tag: String): Boolean + + /** + * 获取授权内容 + * tag:模块ID + */ + fun invokeAuthorizeContent(tag: String) + + /** + * 更新授权状态 + * tag:模块ID + */ + fun updateAuthorizeStatus(tag:String){ + + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeRegister.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeRegister.kt new file mode 100644 index 0000000000..280bc6998a --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/invoke/IMogoAuthorizeRegister.kt @@ -0,0 +1,33 @@ +package com.mogo.module.authorize.authprovider.invoke + +import com.mogo.module.authorize.authprovider.module.IMogoAcquireAuthorizeListener + +interface IMogoAuthorizeRegister { + + /** + * 注冊授权回调 + * tag:module tag + * @see IMogoAcquireAuthorizeListener + */ + fun registerAuthorizeListener(tag: String, listener: IMogoAcquireAuthorizeListener) + + /** + * 反注册授权回调 + * tag:module tag + */ + fun unregisterAuthorizeListener(tag: String) + + /** + * 注册授权信息内容回调 + * tag:module tag + * @see IMogoAuthorizeContentListener + */ + fun registerInvokeAuthorizeContentListener(tag: String, listener: IMogoAuthorizeContentListener) + + /** + * 反注册授权信息内容回调 + * tag:module tag + */ + fun unregisterInvokeAuthorizeContentListener(tag: String) + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IAuthorizeMainInvoke.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IAuthorizeMainInvoke.kt new file mode 100644 index 0000000000..af945e03c7 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IAuthorizeMainInvoke.kt @@ -0,0 +1,24 @@ +package com.mogo.module.authorize.authprovider.launcher + +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeInvoke + +//与Biz业务相同接口实现 +interface IAuthorizeMainInvoke : IMogoAuthorizeInvoke { + + /** + * 同意授权 + * tag:透传模块ID + */ + fun agreeAuthorize(tag: String, agrId: Long, onSuccess: (() -> Unit), onError: ((String) -> Unit)) + + /** + * 不同意授权 + * tag:透传模块ID + */ + fun disAgreeAuthorize(tag: String, agrId: Long, onSuccess: (() -> Unit), onError: ((String) -> Unit)) + + /** + * 是否已经注册回调 + */ + fun hasRegister(tag: String): Boolean +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IMogoAuthorizeMainManager.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IMogoAuthorizeMainManager.kt new file mode 100644 index 0000000000..c20053c616 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IMogoAuthorizeMainManager.kt @@ -0,0 +1,47 @@ +package com.mogo.module.authorize.authprovider.launcher + +import com.alibaba.android.arouter.facade.annotation.Route +import com.mogo.module.authorize.authprovider.invoke.AuthorizeConstant +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeContentListener +import com.mogo.module.authorize.authprovider.launcher.MogoMainAuthorize.Companion.mogoAuthShow +import com.mogo.module.authorize.authprovider.module.IMogoAcquireAuthorizeListener + +@Route(path = AuthorizeConstant.PROVIDER_LAUNCHER) +class IMogoAuthorizeMainManager : IMogoAuthorizeMainProvider { + + override fun hasRegister(tag: String): Boolean { + return mogoAuthShow.hasRegister(tag) + } + + override fun needAuthorize(tag: String): Boolean { + return mogoAuthShow.needAuthorize(tag) + } + + override fun invokeAuthorizeContent(tag: String) { + mogoAuthShow.invokeAuthorizeContent(tag) + } + + override fun agreeAuthorize(tag: String, agrId: Long, onSuccess: (() -> Unit), onError: ((String) -> Unit)) { + mogoAuthShow.agreeAuthorize(tag, agrId, onSuccess, onError) + } + + override fun disAgreeAuthorize(tag: String, agrId: Long, onSuccess: (() -> Unit), onError: ((String) -> Unit)) { + mogoAuthShow.disAgreeAuthorize(tag, agrId, onSuccess, onError) + } + + override fun registerAuthorizeListener(tag: String, listener: IMogoAcquireAuthorizeListener) { + mogoAuthShow.registerAuthorizeListener(tag, listener) + } + + override fun unregisterAuthorizeListener(tag: String) { + mogoAuthShow.unregisterAuthorizeListener(tag) + } + + override fun registerInvokeAuthorizeContentListener(tag: String, listener: IMogoAuthorizeContentListener) { + mogoAuthShow.registerInvokeAuthorizeContentListener(tag, listener) + } + + override fun unregisterInvokeAuthorizeContentListener(tag: String) { + mogoAuthShow.unregisterInvokeAuthorizeContentListener(tag) + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IMogoAuthorizeMainProvider.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IMogoAuthorizeMainProvider.kt new file mode 100644 index 0000000000..8a47fe9fc3 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IMogoAuthorizeMainProvider.kt @@ -0,0 +1,14 @@ +package com.mogo.module.authorize.authprovider.launcher + +import android.content.Context +import com.alibaba.android.arouter.facade.template.IProvider +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeInvoke + +//仅提供给调用业务端(主launcher)使用 +interface IMogoAuthorizeMainProvider : IProvider, IAuthorizeMainInvoke { + + override fun init(context: Context?) { + + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IMogoAuthorizeShow.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IMogoAuthorizeShow.kt new file mode 100644 index 0000000000..f6cbde0907 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/IMogoAuthorizeShow.kt @@ -0,0 +1,8 @@ +package com.mogo.module.authorize.authprovider.launcher + +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeForbiddenVoice + +interface IMogoAuthorizeShow : IMogoAuthorizeForbiddenVoice { + + fun showAuthorizeView() +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/MogoAuthorizeMainController.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/MogoAuthorizeMainController.kt new file mode 100644 index 0000000000..0a0e3f31b9 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/MogoAuthorizeMainController.kt @@ -0,0 +1,74 @@ +package com.mogo.module.authorize.authprovider.launcher + +import com.mogo.module.authorize.authprovider.biz.IMogoAuthorizeController +import com.mogo.module.authorize.authprovider.biz.MogoAuthorizeRegisterHandler +import com.mogo.module.authorize.model.BaseResponse +import com.mogo.module.authorize.model.bean.AGREEMENT_EFFECT +import com.mogo.module.authorize.model.bean.AGREEMENT_NOT_EFFECT +import com.mogo.module.authorize.model.proxy.toAuthorizeType +import com.mogo.module.authorize.net.request +import com.mogo.module.authorize.util.SharedPreferenceUtil.setAuthorizeStatus +import com.mogo.utils.logger.Logger + +object MogoAuthorizeMainController : IMogoAuthorizeController() { + + private val authorizeShowModel: MogoAuthorizeMainModel by lazy { MogoAuthorizeMainModel() } + + @Synchronized + fun agreeAuthorize(tag: String, agrId: Long, onSuccess: (() -> Unit), onError: ((String) -> Unit)) { + + updateAuthorize(agrId, AGREEMENT_EFFECT, { + authorizeSuccess(tag) + setAuthorizeStatus(tag.toAuthorizeType(), true) + onSuccess.invoke() + }, { + val errorMsg = it ?: "agreeAuthorize failed,please check network" + authorizeFailed(tag, errorMsg) + onError.invoke(errorMsg) + }) + } + + @Synchronized + fun disAgreeAuthorize(tag: String, agrId: Long, onSuccess: (() -> Unit), onError: ((String) -> Unit)) { + updateAuthorize(agrId, AGREEMENT_NOT_EFFECT, { + authorizeFailed(tag, "UserDisAgree authorize") + onSuccess.invoke() + }, { + val errorMsg = it ?: "disAgreeAuthorize failed,please check network" + authorizeFailed(tag, errorMsg) + onError.invoke(errorMsg) + }) + } + + private fun updateAuthorize(agrId: Long, agreementStatus: Int, onSuccess: (() -> Unit), onError: ((String?) -> Unit)) { + request> { + loader { + authorizeShowModel.updateAuthorize(agrId, agreementStatus) + } + onSuccess { + onSuccess.invoke() + } + onError { + onError.invoke(it.message) + } + } + } + + private fun authorizeFailed(tag: String, errorMsg: String) { + val acquireAuthorizeListener = MogoAuthorizeRegisterHandler.getAuthorizeListener(tag) + if (acquireAuthorizeListener != null) { + acquireAuthorizeListener.authorizeFailed(errorMsg) + } else { + Logger.d(TAG, "disAgreeAuthorize --- can not find listener by this tag :$tag ") + } + } + + private fun authorizeSuccess(tag: String) { + val acquireAuthListener = MogoAuthorizeRegisterHandler.getAuthorizeListener(tag) + if (acquireAuthListener != null) { + acquireAuthListener.authorizeSuccess() + } else { + Logger.d(TAG, "agreeAuthorize --- can not find listener by this tag :$tag ") + } + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/MogoAuthorizeMainModel.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/MogoAuthorizeMainModel.kt new file mode 100644 index 0000000000..fa8f32cb59 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/MogoAuthorizeMainModel.kt @@ -0,0 +1,17 @@ +package com.mogo.module.authorize.authprovider.launcher + +import com.google.gson.Gson +import com.mogo.commons.network.Utils.getSn +import com.mogo.module.authorize.model.BaseResponse +import com.mogo.module.authorize.model.IMogoAuthorizeModel +import com.mogo.module.authorize.model.bean.UpdateAuthorize + +class MogoAuthorizeMainModel : IMogoAuthorizeModel() { + + suspend fun updateAuthorize(agrId: Long, agreementStatus: Int): BaseResponse { + val updateAuthorize = Gson().toJson(UpdateAuthorize(agrId, agreementStatus)) + val map = mapOf("sn" to getSn(), "data" to updateAuthorize) + return apiCall { getNetWorkApi().updateAuthorize(map) } + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/MogoMainAuthorize.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/MogoMainAuthorize.kt new file mode 100644 index 0000000000..964594e655 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/launcher/MogoMainAuthorize.kt @@ -0,0 +1,92 @@ +package com.mogo.module.authorize.authprovider.launcher + +import android.content.Context +import android.os.Looper +import com.mogo.module.authorize.authprovider.biz.MogoAuthorizeManagerImpl +import com.mogo.module.authorize.authprovider.biz.MogoAuthorizeRegisterHandler +import com.mogo.module.authorize.authprovider.invoke.AuthorizeInvokerConstant.Companion.AUTHORIZE_TYPE_LAUNCHER_MAIN +import com.mogo.module.authorize.layout.AuthorizeDialog +import com.mogo.module.authorize.model.proxy.toAuthorizeType +import com.mogo.module.authorize.util.SharedPreferenceUtil.hasAuth +import com.mogo.utils.logger.Logger + +class MogoMainAuthorize private constructor() : MogoAuthorizeManagerImpl(), IMogoAuthorizeMainProvider { + + companion object { + + const val TAG = "MogoMainAuthorize" + + val mogoAuthShow by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + MogoMainAuthorize() + } + } + + private var mContext: Context? = null + + private var authorizeDialog: AuthorizeDialog? = null + + override fun hasRegister(tag: String): Boolean { + if (tag.isNullOrBlank()) return false + val listener = MogoAuthorizeRegisterHandler.getAuthorizeContentListener(tag) + return listener != null + } + + override fun agreeAuthorize(tag: String, agrId: Long, onSuccess: (() -> Unit), onError: ((String) -> Unit)) { + MogoAuthorizeMainController.agreeAuthorize(tag, agrId, onSuccess, onError) + } + + override fun disAgreeAuthorize(tag: String, agrId: Long, onSuccess: (() -> Unit), onError: ((String) -> Unit)) { + MogoAuthorizeMainController.disAgreeAuthorize(tag, agrId, onSuccess, onError) + } + + fun invokeAuthorizeForShow(context: Context) { + mContext = context + pushLayoutToMainWindow(AUTHORIZE_TYPE_LAUNCHER_MAIN) + } + + fun showAuthorizeView(tag: String, forbiddenVoice: (() -> Unit), onError: ((String) -> Unit)) { + val listener = MogoAuthorizeRegisterHandler.getAuthorizeListener(tag) + if (listener == null) { + onError.invoke("launcher authorizeShowListener is null,must register in MainActivity") + return + } + if (tag.isNullOrBlank()) { + onError.invoke("tag is null,please invoke with tag") + } + if (Thread.currentThread() != Looper.getMainLooper().thread) { + onError.invoke("invoke should be in main thread") + return + } + if (hasAuth(tag.toAuthorizeType())) { + onError.invoke("already authorize,do not repeat operation") + return + } + Logger.d(TAG, "ready to forbidden voice") + forbiddenVoice.invoke() + Logger.d(TAG, "ready to push fragment") + pushLayoutToMainWindow(tag) + } + + fun hideAuthorizeView() { + if (authorizeDialog != null && authorizeDialog!!.isShowing) { + authorizeDialog?.dismiss() + } + } + + private fun pushLayoutToMainWindow(tag: String) { + if (authorizeDialog == null) { + authorizeDialog = AuthorizeDialog(tag, mContext!!) + authorizeDialog!!.setOnDismissListener { + authorizeDialog = null + } + } + if (authorizeDialog!!.isShowing) { + Logger.d(TAG, "User is operation authorization, do not repeat invoke") + return + } else { + Logger.d(TAG, "pushLayoutToMainWindow") + authorizeDialog!!.show() + } + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IAuthorizeModuleInvoke.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IAuthorizeModuleInvoke.kt new file mode 100644 index 0000000000..6bfb811922 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IAuthorizeModuleInvoke.kt @@ -0,0 +1,7 @@ +package com.mogo.module.authorize.authprovider.module + +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeInvoke + +//与Biz业务相同接口实现 +interface IAuthorizeModuleInvoke : IMogoAuthorizeInvoke { +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IMogoAcquireAuthorizeListener.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IMogoAcquireAuthorizeListener.kt new file mode 100644 index 0000000000..99948178ad --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IMogoAcquireAuthorizeListener.kt @@ -0,0 +1,11 @@ +package com.mogo.module.authorize.authprovider.module + +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeForbiddenVoice + +interface IMogoAcquireAuthorizeListener : IMogoAuthorizeForbiddenVoice { + + fun authorizeSuccess() + + fun authorizeFailed(errorMsg: String) + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IMogoAuthorizeModuleManager.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IMogoAuthorizeModuleManager.kt new file mode 100644 index 0000000000..d33c9f66e5 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IMogoAuthorizeModuleManager.kt @@ -0,0 +1,43 @@ +package com.mogo.module.authorize.authprovider.module + +import com.alibaba.android.arouter.facade.annotation.Route +import com.mogo.module.authorize.authprovider.invoke.AuthorizeConstant +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeContentListener +import com.mogo.module.authorize.authprovider.module.MogoModuleAuthorize.Companion.mogoAuth + +@Route(path = AuthorizeConstant.PROVIDER_MODULE) +class IMogoAuthorizeModuleManager : IMogoAuthorizeModuleProvider { + + override fun needAuthorize(tag: String): Boolean { + return mogoAuth.needAuthorize(tag) + } + + override fun invokeAuthorizeForShow() { + mogoAuth.invokeAuthorizeForShow() + } + + override fun invokeAuthorization(tag: String) { + mogoAuth.invokeAuthorization(tag) + } + + override fun invokeAuthorizeContent(tag: String) { + mogoAuth.invokeAuthorizeContent(tag) + } + + override fun registerAuthorizeListener(tag: String, listener: IMogoAcquireAuthorizeListener) { + mogoAuth.registerAuthorizeListener(tag, listener) + } + + override fun unregisterAuthorizeListener(tag: String) { + mogoAuth.unregisterAuthorizeListener(tag) + } + + override fun registerInvokeAuthorizeContentListener(tag: String, listener: IMogoAuthorizeContentListener) { + mogoAuth.registerInvokeAuthorizeContentListener(tag, listener) + } + + override fun unregisterInvokeAuthorizeContentListener(tag: String) { + mogoAuth.unregisterInvokeAuthorizeContentListener(tag) + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IMogoAuthorizeModuleProvider.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IMogoAuthorizeModuleProvider.kt new file mode 100644 index 0000000000..c85b31190f --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/IMogoAuthorizeModuleProvider.kt @@ -0,0 +1,24 @@ +package com.mogo.module.authorize.authprovider.module + +import android.content.Context +import com.alibaba.android.arouter.facade.template.IProvider +import com.mogo.module.authorize.authprovider.invoke.IMogoAuthorizeInvoke + +////仅提供给调用业务端(module)使用 +interface IMogoAuthorizeModuleProvider : IProvider, IMogoAuthorizeInvoke { + + override fun init(context: Context) { + + } + + /** + * 用于没有回调且直接调用授权页面展示 仅Launcher主界面业务使用 + */ + fun invokeAuthorizeForShow() + + /** + * 调用授权页面 + */ + fun invokeAuthorization(tag: String) + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/MogoAuthorizeModuleController.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/MogoAuthorizeModuleController.kt new file mode 100644 index 0000000000..2f38af2f7b --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/MogoAuthorizeModuleController.kt @@ -0,0 +1,7 @@ +package com.mogo.module.authorize.authprovider.module + +import com.mogo.module.authorize.authprovider.biz.IMogoAuthorizeController + +object MogoAuthorizeModuleController : IMogoAuthorizeController() { + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/MogoModuleAuthorize.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/MogoModuleAuthorize.kt new file mode 100644 index 0000000000..e698249eee --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/authprovider/module/MogoModuleAuthorize.kt @@ -0,0 +1,40 @@ +package com.mogo.module.authorize.authprovider.module + +import com.mogo.commons.AbsMogoApplication +import com.mogo.module.authorize.authprovider.biz.MogoAuthorizeManagerImpl +import com.mogo.module.authorize.authprovider.biz.MogoAuthorizeRegisterHandler +import com.mogo.module.authorize.authprovider.launcher.MogoMainAuthorize.Companion.mogoAuthShow + +class MogoModuleAuthorize private constructor() : MogoAuthorizeManagerImpl(), IMogoAuthorizeModuleProvider { + + companion object { + val mogoAuth by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + MogoModuleAuthorize() + } + } + + override fun invokeAuthorizeForShow() { + mogoAuthShow.invokeAuthorizeForShow(AbsMogoApplication.getApp().applicationContext) + } + + override fun invokeAuthorization(tag: String) { + mogoAuthShow.showAuthorizeView(tag, { + //todo SP存储状态 + + }, { errorMsg -> + val listener = MogoAuthorizeRegisterHandler.getAuthorizeListener(tag) + listener?.authorizeFailed(errorMsg) + }) + } + + fun forbiddenVoiceWhenAuthorize(cmd: String) { + val tmpMap = MogoAuthorizeRegisterHandler.getAllAuthorizeListener() + if (tmpMap.isEmpty()) { + return + } + tmpMap.forEach { + val acquireListener = it.value + acquireListener.forbiddenVoiceWhenAuthorize(cmd) + } + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/constant/HttpConstant.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/constant/HttpConstant.kt new file mode 100644 index 0000000000..cbd611b68e --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/constant/HttpConstant.kt @@ -0,0 +1,23 @@ +package com.mogo.module.authorize.constant + +import com.mogo.commons.debug.DebugConfig + +class HttpConstant { + + companion object { + const val HOST_DEV = "http://dzt-test.zhidaohulian.com" + const val HOST_TEST = "http://dzt-test.zhidaohulian.com" + const val HOST_DEMO = "http://dzt-show.zhidaohulian.com" + const val HOST_PRODUCT = "https://dzt.zhidaohulian.com" + + fun getNetHost(): String { + return when (DebugConfig.getNetMode()) { + DebugConfig.NET_MODE_DEV -> HOST_DEV + DebugConfig.NET_MODE_QA -> HOST_TEST + DebugConfig.NET_MODE_DEMO -> HOST_DEMO + else -> HOST_PRODUCT + } + } + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/exception/ApiException.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/exception/ApiException.kt new file mode 100644 index 0000000000..1fbac4455c --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/exception/ApiException.kt @@ -0,0 +1,15 @@ +package com.mogo.module.authorize.exception + + +class ApiException : CommonException { + + companion object { + val NULL_REQUEST_DATA_API_EXCEPTION = ApiException(2, "request data is null") + } + + constructor(code: Int, msg: String) : super(code, msg) + + fun getErrorMsg():String{ + return msg + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/exception/CommonException.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/exception/CommonException.kt new file mode 100644 index 0000000000..927f4819e2 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/exception/CommonException.kt @@ -0,0 +1,18 @@ +package com.mogo.module.authorize.exception + +open class CommonException : Exception { + + companion object { + val NETWORK_EXCEPTION = CommonException(1, "network is error") + val NULL_EXCEPTION = CommonException(1, "error msg is null") + } + + protected var code: Int = 0 + protected var msg: String = "" + + constructor(code: Int, msg: String) : super(msg) { + this.code = code + this.msg = msg + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/layout/AuthorizeController.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/layout/AuthorizeController.kt new file mode 100644 index 0000000000..80af518b8b --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/layout/AuthorizeController.kt @@ -0,0 +1,102 @@ +package com.mogo.module.authorize.layout + +import com.mogo.module.authorize.authprovider.biz.MogoAuthorizeRegisterHandler +import com.mogo.module.authorize.authprovider.launcher.MogoAuthorizeMainController +import com.mogo.module.authorize.authprovider.launcher.MogoMainAuthorize.Companion.mogoAuthShow +import com.mogo.module.authorize.model.bean.Agreement +import com.mogo.module.authorize.util.DateUtil.parseDateToTime +import com.mogo.module.authorize.util.SharedPreferenceUtil.updateAuthorizeVersion +import com.mogo.utils.logger.Logger + +class AuthorizeController { + + companion object { + const val TAG = "AuthorizeController" + } + + private var invokeTag: String? = null + private var updateTime: Long = 0L + + private constructor() + + constructor(invokeTag: String) { + this.invokeTag = invokeTag + Logger.d(TAG, "onCreate invokeTag:$invokeTag") + } + + fun invokeAuthorizationContent(invokeTag: String, before: () -> Unit, + agreementContent: (id: Long, content: String, title: String, bottomContent: String, lastContent: String) -> Unit, + agreementError: () -> Unit) { + before.invoke() + this.invokeTag = invokeTag + MogoAuthorizeMainController.getAuthorizeContent({ + Logger.d(TAG, "ready to get Authorize Content") + }, { + getContentSuccess(it, agreementContent, agreementError) + }, { msg: String -> + getContentFailed(msg, agreementError) + }) + } + + private fun getContentSuccess(userAgreement: Agreement, + agreementContent: (id: Long, content: String, title: String, bottomContent: String, lastContent: String) -> Unit, + agreementError: () -> Unit) { + Logger.d(TAG, "requestContentSuccess userAgreement:$userAgreement") + if (userAgreement.agreementContent.isNotEmpty()) { + val id = userAgreement.tUserAgreementEntity.id + val content = userAgreement.agreementContent[0] + val title = userAgreement.tUserAgreementEntity.title + val bottomContent = userAgreement.tUserAgreementEntity.agreementButtonFirst + val lastContent = userAgreement.tUserAgreementEntity.agreementButtonSecond + val tmpUpdate = userAgreement.tUserAgreementEntity.updateTime + updateTime = parseDateToTime(tmpUpdate) + Logger.d(TAG, "updateTime ===== $updateTime") + agreementContent.invoke(id, content, title, bottomContent, lastContent) + } else { + agreementError.invoke() + } + } + + private fun getContentFailed(errorMsg: String, agreementError: () -> Unit) { + Logger.d(TAG, "requestContentFailed errorMsg:$errorMsg") + agreementError.invoke() + } + + fun agreeAuthorize(tag: String, agreementId: Long, voiceAuthorizeError: () -> Unit) { + mogoAuthShow.agreeAuthorize(tag, agreementId, { + Logger.d(TAG, "agreeAuthorize success") + updateAuthorizeVersion(updateTime) + closeAuthorizeView() + }, { + Logger.d(TAG, "agreeAuthorize failed") + authorizeFailed(voiceAuthorizeError) + }) + } + + fun disAgreeAuthorize(tag: String, agreementId: Long, voiceAuthorizeError: () -> Unit) { + mogoAuthShow.disAgreeAuthorize(tag, agreementId, { + authorizeFailed(voiceAuthorizeError) + }, { + authorizeFailed(voiceAuthorizeError) + }) + } + + private inline fun authorizeFailed(voiceAuthorizeError: () -> Unit) { + voiceAuthorizeError.invoke() + closeAuthorizeView() + } + + private fun closeAuthorizeView() { + invokeTag = null + mogoAuthShow.hideAuthorizeView() + } + + fun onDestroy() { + Logger.d(TAG, "onDestroy invokeTag : $invokeTag") + invokeTag?.let { + MogoAuthorizeRegisterHandler.getAuthorizeContentListener(it)?.requestContentFailed("user exit authorize --- onDestroy") + MogoAuthorizeRegisterHandler.getAuthorizeListener(it)?.authorizeFailed("user exit authorize --- onDestroy") + } + mogoAuthShow.hideAuthorizeView() + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/layout/AuthorizeDialog.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/layout/AuthorizeDialog.kt new file mode 100644 index 0000000000..5d74894005 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/layout/AuthorizeDialog.kt @@ -0,0 +1,203 @@ +package com.mogo.module.authorize.layout + +import android.content.Context +import android.text.Html +import android.view.View +import android.widget.Button +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import com.mogo.commons.AbsMogoApplication +import com.mogo.commons.debug.DebugConfig +import com.mogo.module.authorize.R +import com.mogo.module.authorize.util.AnalyticsUtil +import com.mogo.module.authorize.voice.IVoiceAuthorizeIntentListener +import com.mogo.module.authorize.voice.IVoiceCommandListener +import com.mogo.module.authorize.voice.VoiceUtil +import com.mogo.module.common.dialog.BaseFloatDialog +import com.mogo.utils.TipToast +import com.mogo.utils.logger.Logger +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.async +import kotlinx.coroutines.withContext + +class AuthorizeDialog : BaseFloatDialog, View.OnClickListener, IVoiceCommandListener, IVoiceAuthorizeIntentListener { + + companion object { + const val TAG = "AuthorizeDialog" + } + + private var mContext: Context? = null + private var invokeTag: String? = null + + private var agreementId: Long = 0L + + private var clTopParent: ConstraintLayout? = null + private var clErrorContainer: ConstraintLayout? = null + private var clLoadAuthorizeContainer: ConstraintLayout? = null + private var clContainer: ConstraintLayout? = null + private var clAuthorizeLoading: ConstraintLayout? = null + private var btnAgree: Button? = null + private var btnDisAgree: Button? = null + private var btnLoadingError: Button? = null + private var tvTitle: TextView? = null + private var tvContent: TextView? = null + private var tvButtonContent: TextView? = null + private var tvLastContent: TextView? = null + + private var authorizeController: AuthorizeController? = null + + constructor(invokeTag: String, context: Context) : super(context) { + mContext = context + this.invokeTag = invokeTag + initView() + } + + private fun initView() { + setContentView(R.layout.module_authorize_fragment) + setWrapContent() + initViews() + } + + private fun setWrapContent() { + val mWindow = window + if(DebugConfig.getCarMachineType() != DebugConfig.CAR_MACHINE_TYPE_BYD){ + if (mWindow != null) { + val lp = mWindow.attributes + lp.width = 1024 + lp.height = 600 + mWindow.attributes = lp + } + }else{ + if (mWindow != null) { + val lp = mWindow.attributes + lp.width = 1920 + lp.height = 1000 + mWindow.attributes = lp + } + } + } + + fun initViews() { + Logger.d(TAG, "initView ") + AnalyticsUtil.track(AnalyticsUtil.INVOKE_TRACK_AUTHORIZE_SHOW) + init() + Logger.d(TAG, "invokeTag :$invokeTag") + authorizeController = AuthorizeController(invokeTag!!) + invokeAuthorizationContent() + VoiceUtil.registerAll(this, this) + } + + private fun init() { + clTopParent = findViewById(R.id.clAuthorizeTopParent) + clErrorContainer = findViewById(R.id.clLoadingErrorContainer) + clLoadAuthorizeContainer = findViewById(R.id.clLoadingAuthorizeContainer) + clContainer = findViewById(R.id.clAuthorizeContainer) + clAuthorizeLoading = findViewById(R.id.clAuthorizeLoading) + btnAgree = findViewById(R.id.btnAuthorizeAgree) + btnDisAgree = findViewById(R.id.btnAuthorizeDisAgree) + btnLoadingError = findViewById(R.id.btnAuthorizeLoadingError) + tvTitle = findViewById(R.id.tvAuthorizeTitle) + tvContent = findViewById(R.id.tvAuthorizeContent) + tvButtonContent = findViewById(R.id.tvAuthorizeButtonContent) + tvLastContent = findViewById(R.id.tvAuthorizeLastContent) + btnAgree?.setOnClickListener(this) + btnDisAgree?.setOnClickListener(this) + btnLoadingError?.setOnClickListener(this) + clTopParent?.setOnClickListener(this) + clContainer?.setOnClickListener(this) + clErrorContainer?.setOnClickListener(this) + clLoadAuthorizeContainer?.setOnClickListener(this) + clAuthorizeLoading?.setOnClickListener(this) + } + + private fun readyToAuthorize() { + clErrorContainer?.visibility = View.GONE + clLoadAuthorizeContainer?.visibility = View.VISIBLE + } + + private fun showAuthorizationAgreementContent( + agreementId: Long, + agreementContent: String, + agreementTitle: String, + agreementBottom: String, + agreementLast: String) { + VoiceUtil.speak(AbsMogoApplication.getApp().applicationContext.resources.getString(R.string.module_authorize_agreement_tip), AbsMogoApplication.getApp().applicationContext, this) + this.agreementId = agreementId + clLoadAuthorizeContainer?.visibility = View.GONE + clContainer?.visibility = View.VISIBLE + tvTitle?.text = Html.fromHtml(agreementTitle) + GlobalScope.async(Dispatchers.IO) { + val spannable = Html.fromHtml(agreementContent) + withContext(Dispatchers.Main) { + tvContent?.text = spannable + } + } + tvButtonContent?.text = Html.fromHtml(agreementBottom) + tvLastContent?.text = Html.fromHtml(agreementLast) + } + + private fun showAuthorizationError() { + clLoadAuthorizeContainer?.visibility = View.GONE + clErrorContainer?.visibility = View.VISIBLE + } + + private fun voiceAuthorizeError() { + TipToast.shortTip("授权失败,请稍后重试") + VoiceUtil.speak(AbsMogoApplication.getApp().applicationContext.getString(R.string.module_authorize_failed), AbsMogoApplication.getApp().applicationContext, this) + Logger.d(TAG, "onDestroy") + VoiceUtil.unregisterAll(AbsMogoApplication.getApp().applicationContext, this) + } + + override fun onClick(v: View) { + when (v.id) { + R.id.btnAuthorizeAgree -> { + AnalyticsUtil.track(AnalyticsUtil.INVOKE_TRACK_AUTHORIZE_CLICK, hashMapOf("operation_type" to 1, "operation_result" to 1)) + agreeAuthorize() + } + R.id.btnAuthorizeDisAgree -> { + AnalyticsUtil.track(AnalyticsUtil.INVOKE_TRACK_AUTHORIZE_CLICK, hashMapOf("operation_type" to 1, "operation_result" to 2)) + disAgreeAuthorize() + } + R.id.clLoadingErrorContainer, R.id.btnAuthorizeLoadingError -> { + invokeAuthorizationContent() + } + R.id.clAuthorizeTopParent -> { + Logger.i(TAG, "dismiss authorizeView") + authorizeController?.onDestroy() + } + } + } + + override fun onVoiceCmdAgree() { + AnalyticsUtil.track(AnalyticsUtil.INVOKE_TRACK_AUTHORIZE_CLICK, hashMapOf("operation_type" to 2, "operation_result" to 1)) + agreeAuthorize() + } + + override fun onVoiceCmdDisAgree() { + AnalyticsUtil.track(AnalyticsUtil.INVOKE_TRACK_AUTHORIZE_CLICK, hashMapOf("operation_type" to 2, "operation_result" to 2)) + disAgreeAuthorize() + } + + private fun agreeAuthorize() { + authorizeController?.agreeAuthorize(invokeTag!!, agreementId) { + voiceAuthorizeError() + } + } + + private fun disAgreeAuthorize() { + authorizeController?.disAgreeAuthorize(invokeTag!!, agreementId) { + voiceAuthorizeError() + } + } + + private fun invokeAuthorizationContent() { + authorizeController?.invokeAuthorizationContent(invokeTag!!, { + readyToAuthorize() + }, { id: Long, content: String, title: String, bottomContent: String, lastContent: String -> + showAuthorizationAgreementContent(id, content, title, bottomContent, lastContent) + }, { + showAuthorizationError() + }) + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/layout/AuthorizeLayout.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/layout/AuthorizeLayout.kt new file mode 100644 index 0000000000..adc6968eb1 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/layout/AuthorizeLayout.kt @@ -0,0 +1,179 @@ +package com.mogo.module.authorize.layout + +import android.text.Html +import android.view.LayoutInflater +import android.view.View +import android.widget.Button +import android.widget.TextView +import androidx.constraintlayout.widget.ConstraintLayout +import com.mogo.commons.AbsMogoApplication +import com.mogo.module.authorize.R +import com.mogo.module.authorize.util.AnalyticsUtil +import com.mogo.module.authorize.util.AnalyticsUtil.INVOKE_TRACK_AUTHORIZE_CLICK +import com.mogo.module.authorize.util.AnalyticsUtil.INVOKE_TRACK_AUTHORIZE_SHOW +import com.mogo.module.authorize.voice.IVoiceAuthorizeIntentListener +import com.mogo.module.authorize.voice.IVoiceCommandListener +import com.mogo.module.authorize.voice.VoiceUtil +import com.mogo.utils.logger.Logger +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.async +import kotlinx.coroutines.withContext + +class AuthorizeLayout(private val invokeTag: String) : View.OnClickListener, IVoiceCommandListener, IVoiceAuthorizeIntentListener { + + companion object { + const val TAG = "AuthorizeLayout" + } + + private var agreementId: Long = 0L + + private var clTopParent: ConstraintLayout? = null + private var clErrorContainer: ConstraintLayout? = null + private var clLoadAuthorizeContainer: ConstraintLayout? = null + private var clContainer: ConstraintLayout? = null + private var clAuthorizeLoading: ConstraintLayout? = null + private var btnAgree: Button? = null + private var btnDisAgree: Button? = null + private var btnLoadingError: Button? = null + private var tvTitle: TextView? = null + private var tvContent: TextView? = null + private var tvButtonContent: TextView? = null + private var tvLastContent: TextView? = null + + private lateinit var layoutInflater: View + private var authorizeController: AuthorizeController? = null + + fun getLayoutView(): View { + layoutInflater = LayoutInflater.from(AbsMogoApplication.getApp().applicationContext).inflate(getLayoutId(), null) + initViews(layoutInflater) + return layoutInflater + } + + fun getLayoutId(): Int { + return R.layout.module_authorize_fragment + } + + fun initViews(mRootView: View) { + Logger.d(TAG, "initView ") + AnalyticsUtil.track(INVOKE_TRACK_AUTHORIZE_SHOW) + init(mRootView) + Logger.d(TAG, "invokeTag :$invokeTag") + authorizeController = AuthorizeController(invokeTag) + invokeAuthorizationContent() + VoiceUtil.registerAll(this, this) + } + + private fun init(mRootView: View) { + clTopParent = mRootView.findViewById(R.id.clAuthorizeTopParent) + clErrorContainer = mRootView.findViewById(R.id.clLoadingErrorContainer) + clLoadAuthorizeContainer = mRootView.findViewById(R.id.clLoadingAuthorizeContainer) + clContainer = mRootView.findViewById(R.id.clAuthorizeContainer) + clAuthorizeLoading = mRootView.findViewById(R.id.clAuthorizeLoading) + btnAgree = mRootView.findViewById(R.id.btnAuthorizeAgree) + btnDisAgree = mRootView.findViewById(R.id.btnAuthorizeDisAgree) + btnLoadingError = mRootView.findViewById(R.id.btnAuthorizeLoadingError) + tvTitle = mRootView.findViewById(R.id.tvAuthorizeTitle) + tvContent = mRootView.findViewById(R.id.tvAuthorizeContent) + tvButtonContent = mRootView.findViewById(R.id.tvAuthorizeButtonContent) + tvLastContent = mRootView.findViewById(R.id.tvAuthorizeLastContent) + btnAgree?.setOnClickListener(this) + btnDisAgree?.setOnClickListener(this) + btnLoadingError?.setOnClickListener(this) + clTopParent?.setOnClickListener(this) + clContainer?.setOnClickListener(this) + clErrorContainer?.setOnClickListener(this) + clLoadAuthorizeContainer?.setOnClickListener(this) + clAuthorizeLoading?.setOnClickListener(this) + } + + private fun readyToAuthorize() { + clErrorContainer?.visibility = View.GONE + clLoadAuthorizeContainer?.visibility = View.VISIBLE + } + + private fun showAuthorizationAgreementContent( + agreementId: Long, + agreementContent: String, + agreementTitle: String, + agreementBottom: String, + agreementLast: String) { + VoiceUtil.speak(AbsMogoApplication.getApp().applicationContext.resources.getString(R.string.module_authorize_agreement_tip), AbsMogoApplication.getApp().applicationContext, this) + this.agreementId = agreementId + clLoadAuthorizeContainer?.visibility = View.GONE + clContainer?.visibility = View.VISIBLE + tvTitle?.text = Html.fromHtml(agreementTitle) + GlobalScope.async(Dispatchers.IO) { + val spannable = Html.fromHtml(agreementContent) + withContext(Dispatchers.Main) { + tvContent?.text = spannable + } + } + tvButtonContent?.text = Html.fromHtml(agreementBottom) + tvLastContent?.text = Html.fromHtml(agreementLast) + } + + private fun showAuthorizationError() { + clLoadAuthorizeContainer?.visibility = View.GONE + clErrorContainer?.visibility = View.VISIBLE + } + + private fun voiceAuthorizeError() { + VoiceUtil.speak(AbsMogoApplication.getApp().applicationContext.getString(R.string.module_authorize_failed), AbsMogoApplication.getApp().applicationContext, this) + Logger.d(TAG, "onDestroy") + VoiceUtil.unregisterAll(AbsMogoApplication.getApp().applicationContext, this) + } + + override fun onClick(v: View) { + when (v.id) { + R.id.btnAuthorizeAgree -> { + AnalyticsUtil.track(INVOKE_TRACK_AUTHORIZE_CLICK, hashMapOf("operation_type" to 1, "operation_result" to 1)) + agreeAuthorize() + } + R.id.btnAuthorizeDisAgree -> { + AnalyticsUtil.track(INVOKE_TRACK_AUTHORIZE_CLICK, hashMapOf("operation_type" to 1, "operation_result" to 2)) + disAgreeAuthorize() + } + R.id.clLoadingErrorContainer, R.id.btnAuthorizeLoadingError -> { + invokeAuthorizationContent() + } + R.id.clAuthorizeTopParent-> { + Logger.i(TAG,"dismiss authorizeView") + authorizeController?.onDestroy() + } + } + } + + override fun onVoiceCmdAgree() { + AnalyticsUtil.track(INVOKE_TRACK_AUTHORIZE_CLICK, hashMapOf("operation_type" to 2, "operation_result" to 1)) + agreeAuthorize() + } + + override fun onVoiceCmdDisAgree() { + AnalyticsUtil.track(INVOKE_TRACK_AUTHORIZE_CLICK, hashMapOf("operation_type" to 2, "operation_result" to 2)) + disAgreeAuthorize() + } + + private fun agreeAuthorize() { + authorizeController?.agreeAuthorize(invokeTag, agreementId) { + voiceAuthorizeError() + } + } + + private fun disAgreeAuthorize() { + authorizeController?.disAgreeAuthorize(invokeTag, agreementId) { + voiceAuthorizeError() + } + } + + private fun invokeAuthorizationContent() { + authorizeController?.invokeAuthorizationContent(invokeTag, { + readyToAuthorize() + }, { id: Long, content: String, title: String, bottomContent: String, lastContent: String -> + showAuthorizationAgreementContent(id, content, title, bottomContent, lastContent) + }, { + showAuthorizationError() + }) + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/BaseRepository.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/BaseRepository.kt new file mode 100644 index 0000000000..2e82101711 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/BaseRepository.kt @@ -0,0 +1,23 @@ +package com.mogo.module.authorize.model + +import com.alibaba.android.arouter.launcher.ARouter +import com.mogo.module.authorize.constant.HttpConstant +import com.mogo.module.authorize.net.AuthorizeApi +import com.mogo.service.IMogoServiceApis +import com.mogo.service.MogoServicePaths + +open class BaseRepository { + + suspend fun apiCall(call: suspend () -> BaseResponse): BaseResponse { + return call.invoke() + } + + fun getNetWorkApi(): AuthorizeApi { + var serviceApi: IMogoServiceApis? = null + val mogoService = ARouter.getInstance().build(MogoServicePaths.PATH_SERVICE_APIS).navigation() + if (mogoService is IMogoServiceApis) { + serviceApi = mogoService + } + return serviceApi!!.networkApi.createNoCallAdapter(AuthorizeApi::class.java, HttpConstant.getNetHost()) + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/BaseResponse.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/BaseResponse.kt new file mode 100644 index 0000000000..963747434a --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/BaseResponse.kt @@ -0,0 +1,6 @@ +package com.mogo.module.authorize.model + + +class BaseResponse(val code: Int, val msg: String, val detailMsg: String, val result: T) { + +} diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/IMogoAuthorizeModel.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/IMogoAuthorizeModel.kt new file mode 100644 index 0000000000..0b79f7c692 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/IMogoAuthorizeModel.kt @@ -0,0 +1,26 @@ +package com.mogo.module.authorize.model + +import com.google.gson.Gson +import com.mogo.commons.network.Utils.getSn +import com.mogo.module.authorize.model.bean.AgreementData +import com.mogo.module.authorize.model.bean.AgreementStatus +import com.mogo.module.authorize.model.bean.RequestUserAgreement + +open class IMogoAuthorizeModel : BaseRepository() { + + companion object { + const val TAG = "IMogoAuthorizeModel" + } + + suspend fun invokeAuthorizeContent(agreementType: Int, needContent: Boolean = false): BaseResponse { + val requestUserAgreement = Gson().toJson(RequestUserAgreement(agreementType, needContent)) + val map = mapOf("sn" to getSn(), "data" to requestUserAgreement) + return apiCall { getNetWorkApi().getAuthorizeContent(map) } + } + + suspend fun invokeIfNeedAuthorize(agreementType: Int): BaseResponse { + val requestUserAgreement = Gson().toJson(RequestUserAgreement(agreementType)) + val map = mapOf("sn" to getSn(), "data" to requestUserAgreement) + return apiCall { getNetWorkApi().checkIfNeedAuthorize(map) } + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/bean/Agreement.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/bean/Agreement.kt new file mode 100644 index 0000000000..bec8a198d5 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/bean/Agreement.kt @@ -0,0 +1,37 @@ +package com.mogo.module.authorize.model.bean + +const val AGREEMENT_EFFECT = 1 //用户协议生效 +const val AGREEMENT_NOT_EFFECT = 2 //用户协议不生效 + +class RequestUserAgreement{ + var agreementType:Int + var want:Boolean = false + + constructor(agreementType:Int){ + this.agreementType = agreementType + } + + constructor(agreementType: Int, want: Boolean) { + this.agreementType = agreementType + this.want = want + } +} + +data class AgreementStatus(val agreementStatus:Int) + +data class AgreementData(val agreement: Agreement) + +data class Agreement(var tUserAgreementEntity: TUserAgreementEntity, var agreementContent: List) + +data class TUserAgreementEntity( + val id: Long, //协议ID + val title: String, //标题 + val subhead: String, //副标题 + val agreementButtonFirst: String, //底部标题1 + val agreementButtonSecond: String, //底部标题2 + val agreementType: Int, //协议类型 + val agreementVersion: String, //协议版本 + val agreementUserType: String, //协议适用用户 + val agreementStatus: Int, //协议状态 1:生效 2:未生效 + val createTime: String, //协议创建时间 + val updateTime: String) //协议更新时间 diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/bean/UpdateAuthorize.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/bean/UpdateAuthorize.kt new file mode 100644 index 0000000000..305be207a8 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/bean/UpdateAuthorize.kt @@ -0,0 +1,16 @@ +package com.mogo.module.authorize.model.bean + +class UpdateAuthorize { + var agrId: Long + var status: Int + + constructor(agrId: Long, status: Int) { + this.agrId = agrId + this.status = status + } + + override fun toString(): String { + return "UpdateAuthorize(agrId=$agrId, status=$status)" + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/proxy/AuthorizeProxy.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/proxy/AuthorizeProxy.kt new file mode 100644 index 0000000000..093b4b20e8 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/proxy/AuthorizeProxy.kt @@ -0,0 +1,68 @@ +package com.mogo.module.authorize.model.proxy + +import com.mogo.module.authorize.authprovider.invoke.AuthorizeInvokerConstant.Companion.AUTHORIZE_TYPE_AUXILIARY_DRIVING +import com.mogo.module.authorize.authprovider.invoke.AuthorizeInvokerConstant.Companion.AUTHORIZE_TYPE_CALL_CHAT +import com.mogo.module.authorize.authprovider.invoke.AuthorizeInvokerConstant.Companion.AUTHORIZE_TYPE_LAUNCHER_MAIN +import com.mogo.module.authorize.authprovider.invoke.AuthorizeInvokerConstant.Companion.AUTHORIZE_TYPE_LAUNCHER_SHARE +import com.mogo.module.authorize.authprovider.invoke.AuthorizeInvokerConstant.Companion.AUTHORIZE_TYPE_LAUNCHER_SHARE_MUSIC +import com.mogo.module.authorize.authprovider.invoke.AuthorizeInvokerConstant.Companion.AUTHORIZE_TYPE_LAUNCHER_SHARE_NOVELTY +import com.mogo.module.authorize.authprovider.invoke.AuthorizeInvokerConstant.Companion.AUTHORIZE_TYPE_NOVELTY +import com.mogo.module.authorize.authprovider.invoke.AuthorizeInvokerConstant.Companion.AUTHORIZE_TYPE_TAN_LU + + +fun String.toAuthorizeType(): Int { + return AuthorizeProxy.getAuthorizeType(this) +} + +class AuthorizeProxy { + + companion object { + + const val TAG = "AuthorizeProxy" + + fun getAuthorizeType(authorizeName: String): Int { + if (authorizeName.isNullOrBlank()) { + return -1 + } + return when (authorizeName) { + AUTHORIZE_TYPE_LAUNCHER_MAIN, + AUTHORIZE_TYPE_LAUNCHER_SHARE_NOVELTY, + AUTHORIZE_TYPE_LAUNCHER_SHARE_MUSIC, + AUTHORIZE_TYPE_LAUNCHER_SHARE -> 0 + AUTHORIZE_TYPE_TAN_LU -> 1 + AUTHORIZE_TYPE_CALL_CHAT -> 2 + AUTHORIZE_TYPE_NOVELTY -> 3 + AUTHORIZE_TYPE_AUXILIARY_DRIVING -> 4 + else -> -1 + } + } + } + + enum class AuthorizeEnum : IAuthorizeOperation { + LAUNCHER_MAIN(0, AUTHORIZE_TYPE_LAUNCHER_MAIN), + LAUNCHER_SHARE_NOVELTY(0, AUTHORIZE_TYPE_LAUNCHER_SHARE_NOVELTY), + LAUNCHER_SHARE_MUSIC(0, AUTHORIZE_TYPE_LAUNCHER_SHARE_MUSIC), + LAUNCHER_SHARE(0, AUTHORIZE_TYPE_LAUNCHER_SHARE), + CALL_CHAT(1, AUTHORIZE_TYPE_TAN_LU), + TANLU(2, AUTHORIZE_TYPE_CALL_CHAT), + NOVELTY(3, AUTHORIZE_TYPE_NOVELTY), + AUXILIARY_DRIVING(4, AUTHORIZE_TYPE_AUXILIARY_DRIVING); + + private var authorizeType = 0 + private var authorizeName: String? = null + + constructor(authorizeType: Int, authorizeName: String?) { + this.authorizeType = authorizeType + this.authorizeName = authorizeName + } + + override fun getOperationName(): String? { + return authorizeName + } + + override fun getAcquireId(): Int { + return authorizeType + } + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/proxy/IAuthorizeOperation.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/proxy/IAuthorizeOperation.kt new file mode 100644 index 0000000000..952246213b --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/model/proxy/IAuthorizeOperation.kt @@ -0,0 +1,8 @@ +package com.mogo.module.authorize.model.proxy + +interface IAuthorizeOperation { + + fun getOperationName(): String? + + fun getAcquireId(): Int +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/net/AuthorizeApi.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/net/AuthorizeApi.kt new file mode 100644 index 0000000000..71163940dd --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/net/AuthorizeApi.kt @@ -0,0 +1,27 @@ +package com.mogo.module.authorize.net + +import com.mogo.module.authorize.model.BaseResponse +import com.mogo.module.authorize.model.bean.AgreementData +import com.mogo.module.authorize.model.bean.AgreementStatus +import retrofit2.http.FieldMap +import retrofit2.http.FormUrlEncoded +import retrofit2.http.POST + +interface AuthorizeApi { + + //获取授权内容· + @FormUrlEncoded + @POST("yycp-channelManager/agreement/findUserAgreement") + suspend fun getAuthorizeContent(@FieldMap authorizeContent: Map): BaseResponse + + //更新授权状态 + @FormUrlEncoded + @POST("yycp-channelManager/agreement/updateStatus") + suspend fun updateAuthorize(@FieldMap updateStatus: Map): BaseResponse + + //查询是否要授权 + @FormUrlEncoded + @POST("yycp-channelManager/agreement/queryUserAuthorizeStatusByType") + suspend fun checkIfNeedAuthorize(@FieldMap needAuthorize: Map): BaseResponse + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/net/CoroutineDSL.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/net/CoroutineDSL.kt new file mode 100644 index 0000000000..f9d611409a --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/net/CoroutineDSL.kt @@ -0,0 +1,84 @@ +package com.mogo.module.authorize.net + +import com.mogo.module.authorize.exception.ApiException +import com.mogo.module.authorize.exception.ApiException.Companion.NULL_REQUEST_DATA_API_EXCEPTION +import com.mogo.module.authorize.exception.CommonException.Companion.NETWORK_EXCEPTION +import com.mogo.module.authorize.exception.CommonException.Companion.NULL_EXCEPTION +import com.mogo.module.authorize.model.BaseResponse +import kotlinx.coroutines.* +import java.net.SocketTimeoutException +import java.net.UnknownHostException +import java.util.concurrent.TimeoutException + +class Request { + private lateinit var loader: suspend () -> T + + private var start: (() -> Unit)? = null + + private var onSuccess: ((T) -> Unit)? = null + + private var onError: ((java.lang.Exception) -> Unit)? = null + + private var onComplete: (() -> Unit)? = null + + infix fun loader(loader: suspend () -> T) { + this.loader = loader + } + + infix fun start(start: (() -> Unit)?) { + this.start = start + } + + infix fun onSuccess(onSuccess: ((T) -> Unit)?) { + this.onSuccess = onSuccess + } + + infix fun onError(onError: ((java.lang.Exception) -> Unit)?) { + this.onError = onError + } + + infix fun onComplete(onComplete: (() -> Unit)?) { + this.onComplete = onComplete + } + + fun request() { + + GlobalScope.launch(context = Dispatchers.Main) { + + start?.invoke() + try { + val deferred = GlobalScope.async(Dispatchers.IO, start = CoroutineStart.LAZY) { + loader() + } + val result = deferred.await() + if (result != null && result is BaseResponse<*>) { + if (result.code == 0) { + onSuccess?.invoke(result) + } else { + throw ApiException(result.code, result.msg) + } + } else { + throw NULL_REQUEST_DATA_API_EXCEPTION + } + } catch (e: Exception) { + e.printStackTrace() + if (e == null) { + onError?.invoke(NULL_EXCEPTION) + return@launch + } + when (e) { + is UnknownHostException -> onError?.invoke(NETWORK_EXCEPTION) + is TimeoutException -> onError?.invoke(NETWORK_EXCEPTION) + is SocketTimeoutException -> onError?.invoke(NETWORK_EXCEPTION) + else -> onError?.invoke(java.lang.Exception(e.message ?: "")) + } + } finally { + onComplete?.invoke() + } + } + } +} + +inline fun request(buildRequest: Request.() -> Unit) { + Request().apply(buildRequest).request() +} diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/util/AnalyticsUtil.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/util/AnalyticsUtil.kt new file mode 100644 index 0000000000..bb08c3350f --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/util/AnalyticsUtil.kt @@ -0,0 +1,24 @@ +package com.mogo.module.authorize.util + +import com.alibaba.android.arouter.launcher.ARouter +import com.mogo.service.IMogoServiceApis +import com.mogo.service.MogoServicePaths +import com.mogo.service.analytics.IMogoAnalytics + +object AnalyticsUtil { + + const val INVOKE_TRACK_AUTHORIZE_SHOW = "Launcher_Privacy_protocol_Show" + const val INVOKE_TRACK_AUTHORIZE_CLICK = "Launcher_Privacy_protocol_click" + + private var trackRouter: IMogoAnalytics? = null + + fun track(eventType: String, data: MutableMap? = hashMapOf()) { + if (trackRouter == null) { + val arouter = ARouter.getInstance().build(MogoServicePaths.PATH_SERVICE_APIS).navigation() + if (arouter is IMogoServiceApis) { + trackRouter = arouter.analyticsApi + } + } + trackRouter!!.track(eventType, data) + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/util/DateUtil.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/util/DateUtil.kt new file mode 100644 index 0000000000..cba4cd0248 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/util/DateUtil.kt @@ -0,0 +1,11 @@ +package com.mogo.module.authorize.util + +import java.util.* + +object DateUtil { + + fun parseDateToTime(tmpDate: String): Long { + val time = Date(tmpDate) + return time.time + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/util/SharedPreferenceUtil.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/util/SharedPreferenceUtil.kt new file mode 100644 index 0000000000..d585622cde --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/util/SharedPreferenceUtil.kt @@ -0,0 +1,35 @@ +package com.mogo.module.authorize.util + +import com.mogo.commons.AbsMogoApplication +import com.mogo.utils.storage.SharedPrefsMgr + +object SharedPreferenceUtil { + + private const val HAS_AUTH = "HAS_AUTH" + private const val HAS_GUIDE = "HAS_GUIDE" + private const val AUTHORIZE_UPDATE_TIME = "AUTHORIZE_UPDATE_TIME" + + fun needAuthorization(type: Int): Boolean { + return !hasAuth(type) + } + + fun hasAuth(type: Int): Boolean { + return SharedPrefsMgr.getInstance(AbsMogoApplication.getApp()).getBoolean(HAS_AUTH + type, false) + } + + fun setAuthorizeStatus(type: Int, authorize: Boolean) { + SharedPrefsMgr.getInstance(AbsMogoApplication.getApp()).putBoolean(HAS_AUTH + type, authorize) + } + + fun updateAuthorizeVersion(updateTime: Long) { + SharedPrefsMgr.getInstance(AbsMogoApplication.getApp()).putLong(AUTHORIZE_UPDATE_TIME, updateTime) + } + + fun getAuthorizeVersion(): Long { + return SharedPrefsMgr.getInstance(AbsMogoApplication.getApp()).getLong(AUTHORIZE_UPDATE_TIME, 0L) + } + + fun hasGuide(): Boolean { + return SharedPrefsMgr.getInstance(AbsMogoApplication.getApp()).getBoolean(HAS_GUIDE, false) + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/view/AutoSplitTextView.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/view/AutoSplitTextView.kt new file mode 100644 index 0000000000..e3983a4a7e --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/view/AutoSplitTextView.kt @@ -0,0 +1,53 @@ +package com.mogo.module.authorize.view + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.util.AttributeSet +import android.widget.TextView + +class AutoSplitTextView : TextView { + + private var textShowWidth: Float = 0f + private var paint: Paint? = null + + constructor(context: Context?) : super(context, null) + constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) { + init() + } + + constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { + init() + } + + private fun init() { + paint = Paint() + } + + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + textShowWidth = (this.measuredWidth - paddingLeft - paddingRight).toFloat() + var lineCount = 0 + if (text.toString().isNullOrBlank()) return + val textCharArray = text.toString().toCharArray() + var drawWidth = 0f + var charWidth: Float + for (i in 0..textCharArray.size) { + charWidth = paint!!.measureText(textCharArray, i, 1) + if (textCharArray[i] == '\n') { + lineCount++ + drawWidth = 0f + continue + } + if (textShowWidth - drawWidth < charWidth) { + lineCount++ + drawWidth = 0f + } + canvas.drawText(textCharArray, i, 1, paddingLeft + drawWidth, (lineCount + 1) * textSize, paint) + drawWidth += charWidth + } + height = (lineCount + 1) * textSize as Int + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/IVoiceAuthorizeIntentListener.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/IVoiceAuthorizeIntentListener.kt new file mode 100644 index 0000000000..f5d2a4fcb6 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/IVoiceAuthorizeIntentListener.kt @@ -0,0 +1,18 @@ +package com.mogo.module.authorize.voice + +import android.content.Intent +import com.mogo.service.intent.IMogoIntentListener +import com.mogo.utils.logger.Logger + +private const val IVoiceIntentTAG = "IVoiceAuthorizeIntentListener" + +interface IVoiceAuthorizeIntentListener : IMogoIntentListener, IVoiceBusinessListener { + + override fun onIntentReceived(cmd: String?, intent: Intent?) { + Logger.i(IVoiceIntentTAG, "cmd -> $cmd") + if (intent != null && cmd != null) { + VoiceManager.handleOnIntentCmd(cmd, intent, this) + } + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/IVoiceBusinessListener.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/IVoiceBusinessListener.kt new file mode 100644 index 0000000000..b9792d1126 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/IVoiceBusinessListener.kt @@ -0,0 +1,8 @@ +package com.mogo.module.authorize.voice + +interface IVoiceBusinessListener { + + fun onVoiceCmdAgree() + + fun onVoiceCmdDisAgree() +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/IVoiceCommandListener.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/IVoiceCommandListener.kt new file mode 100644 index 0000000000..bf50a36ae6 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/IVoiceCommandListener.kt @@ -0,0 +1,35 @@ +package com.mogo.module.authorize.voice + +import com.mogo.commons.voice.IMogoVoiceCmdCallBack +import com.mogo.utils.logger.Logger + +private const val IVoiceCommandTAG = "IVoiceCommandTAG" + +interface IVoiceCommandListener : IMogoVoiceCmdCallBack, IVoiceBusinessListener { + + override fun onCmdSelected(cmd: String?) { + Logger.i( + IVoiceCommandTAG, "onCmdSelected cmd:${cmd ?: "cmd is null"}" + ) + cmd?.let { + VoiceManager.handleOnCmdSelected(cmd, this) + } + } + + override fun onCmdAction(speakText: String?) { + + } + + override fun onCmdCancel(speakText: String?) { + + } + + override fun onSpeakSelectTimeOut(speakText: String?) { + + } + + override fun onSpeakEnd(speakText: String?) { + Logger.i(IVoiceCommandTAG, "onSpeakEnd --- speakText : $speakText") + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/VoiceManager.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/VoiceManager.kt new file mode 100644 index 0000000000..8fdef5a631 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/VoiceManager.kt @@ -0,0 +1,42 @@ +package com.mogo.module.authorize.voice + +import android.content.Intent +import com.mogo.module.authorize.voice.VoiceUtil.VOICE_INTENT_AGREE +import com.mogo.module.authorize.voice.VoiceUtil.VOICE_INTENT_DISAGREE +import com.mogo.module.authorize.voice.VoiceUtil.VOICE_REGISTER_AUTHORIZE_AGREE +import com.mogo.module.authorize.voice.VoiceUtil.VOICE_REGISTER_AUTHORIZE_DISAGREE +import com.mogo.utils.logger.Logger + +object VoiceManager { + + private const val TAG = "VoiceManager" + + fun handleOnCmdSelected(cmd: String, listener: IVoiceCommandListener) { + Logger.i(TAG, "handleOnCmdSelected: cmd ---> $cmd") + when (cmd) { + VOICE_REGISTER_AUTHORIZE_AGREE -> { + Logger.i(TAG, "语音免唤醒 同意") + listener.onVoiceCmdAgree() + } + VOICE_REGISTER_AUTHORIZE_DISAGREE -> { + Logger.i(TAG, "语音免唤醒 不同意") + listener.onVoiceCmdDisAgree() + } + } + } + + fun handleOnIntentCmd(cmd: String, intent: Intent, listener: IVoiceAuthorizeIntentListener) { + Logger.i(TAG, "handleOnIntentCmd: cmd -> $cmd") + when (cmd) { + VOICE_INTENT_AGREE -> { + Logger.i(TAG, "语音唤醒 同意") + listener.onVoiceCmdAgree() + } + VOICE_INTENT_DISAGREE -> { + Logger.i(TAG, "语音唤醒 不同意") + listener.onVoiceCmdDisAgree() + } + } + } + +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/VoiceUtil.kt b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/VoiceUtil.kt new file mode 100644 index 0000000000..6d0d0e8b45 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/java/com/mogo/module/authorize/voice/VoiceUtil.kt @@ -0,0 +1,93 @@ +package com.mogo.module.authorize.voice + +import android.content.Context +import com.alibaba.android.arouter.launcher.ARouter +import com.mogo.commons.AbsMogoApplication +import com.mogo.commons.voice.AIAssist +import com.mogo.service.IMogoServiceApis +import com.mogo.service.MogoServicePaths +import com.mogo.service.intent.IMogoIntentManager +import com.mogo.utils.logger.Logger + +object VoiceUtil { + + private const val TAG = "VoiceUtil" + private var intentRegister: IMogoIntentManager? = null + + init { + Logger.i(TAG, "init") + val register = + ARouter.getInstance().build(MogoServicePaths.PATH_SERVICE_APIS).navigation() + if (register is IMogoServiceApis) { + intentRegister = register.intentManagerApi + } + } + + //WakeUp Command (Intent) + const val VOICE_INTENT_AGREE = "com.zhidao.agree" //同意 + const val VOICE_INTENT_DISAGREE = "com.zhiao.disagree" //不同意 + + //unWakeUp Command + const val VOICE_REGISTER_AUTHORIZE_AGREE = "CMD_AUTHORIZATION_AGREE" + private val agreeArray: Array = arrayOf("同意", "调整", "好的") + const val VOICE_REGISTER_AUTHORIZE_DISAGREE = "CMD_AUTHORIZATION_DISAGREE" + private val disAgreeArray: Array = arrayOf("不同意", "不调整") + + private var hasRegister = false + + fun speak(content: String, context: Context, listener: IVoiceCommandListener) { + AIAssist.getInstance(context).speakTTSVoice(content, listener) + } + + fun registerAll( + voiceCommand: IVoiceCommandListener, + intentCommand: IVoiceAuthorizeIntentListener, context: Context = AbsMogoApplication.getApp().applicationContext + ) { + if (!hasRegister) { + hasRegister = true + registerAgree(context, voiceCommand, intentCommand) + registerDisAgree(context, voiceCommand, intentCommand) + } + } + + private fun registerAgree( + context: Context, + voiceCommand: IVoiceCommandListener, + intentCommand: IVoiceAuthorizeIntentListener + ) { + Logger.i(TAG, "registerAgree") + AIAssist.getInstance(context) + .registerUnWakeupCommand( + VOICE_REGISTER_AUTHORIZE_AGREE, + agreeArray, voiceCommand + ) + intentRegister?.registerIntentListener(VOICE_INTENT_AGREE, intentCommand) + } + + private fun registerDisAgree( + context: Context, + voiceCommand: IVoiceCommandListener, + intentCommand: IVoiceAuthorizeIntentListener + ) { + Logger.i(TAG, "registerDisAgree") + AIAssist.getInstance(context) + .registerUnWakeupCommand( + VOICE_REGISTER_AUTHORIZE_DISAGREE, + disAgreeArray, voiceCommand + ) + intentRegister?.registerIntentListener(VOICE_INTENT_DISAGREE, intentCommand) + } + + fun unregisterAll(context: Context, listener: IVoiceAuthorizeIntentListener) { + Logger.i(TAG, "unregister All") + AIAssist.getInstance(context).unregisterUnWakeupCommand(VOICE_REGISTER_AUTHORIZE_AGREE) + AIAssist.getInstance(context).unregisterUnWakeupCommand(VOICE_REGISTER_AUTHORIZE_DISAGREE) + hasRegister = false + + Logger.i(TAG, "unregister IntentVoiceCommand --- intentRegister:$intentRegister") + intentRegister?.let { + it.unregisterIntentListener(VOICE_INTENT_AGREE, listener) + it.unregisterIntentListener(VOICE_INTENT_DISAGREE, listener) + } + } +} \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_blue_corner.xml b/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_blue_corner.xml new file mode 100644 index 0000000000..c2d1fec152 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_blue_corner.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_blue_left_corner.xml b/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_blue_left_corner.xml new file mode 100644 index 0000000000..8c950afee3 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_blue_left_corner.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_dark_corner.xml b/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_dark_corner.xml new file mode 100644 index 0000000000..86e673bca6 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_dark_corner.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_dark_right_corner.xml b/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_dark_right_corner.xml new file mode 100644 index 0000000000..086f0e93fa --- /dev/null +++ b/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_selector_dark_right_corner.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_shape_drak_top_corner.xml b/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_shape_drak_top_corner.xml new file mode 100644 index 0000000000..38ff34eb71 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/res/drawable-xhdpi-1920x1000/module_authorize_shape_drak_top_corner.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_scrollbar.png b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_scrollbar.png new file mode 100644 index 0000000000..1bb3d4882d Binary files /dev/null and b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_scrollbar.png differ diff --git a/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_blue_corner.xml b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_blue_corner.xml new file mode 100644 index 0000000000..c2d1fec152 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_blue_corner.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_blue_left_corner.xml b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_blue_left_corner.xml new file mode 100644 index 0000000000..6399ca294a --- /dev/null +++ b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_blue_left_corner.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_dark_corner.xml b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_dark_corner.xml new file mode 100644 index 0000000000..1b8bbd3159 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_dark_corner.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_dark_right_corner.xml b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_dark_right_corner.xml new file mode 100644 index 0000000000..d866721b3b --- /dev/null +++ b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_selector_dark_right_corner.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_shape_drak_top_corner.xml b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_shape_drak_top_corner.xml new file mode 100644 index 0000000000..0f2dab89cb --- /dev/null +++ b/modules/mogo-module-authorize/src/main/res/drawable/module_authorize_shape_drak_top_corner.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/modules/mogo-module-authorize/src/main/res/layout-xhdpi-1920x1000/module_authorize_fragment.xml b/modules/mogo-module-authorize/src/main/res/layout-xhdpi-1920x1000/module_authorize_fragment.xml new file mode 100644 index 0000000000..f3d940ee26 --- /dev/null +++ b/modules/mogo-module-authorize/src/main/res/layout-xhdpi-1920x1000/module_authorize_fragment.xml @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + +