This commit is contained in:
unknown
2020-07-30 19:25:47 +08:00
3211 changed files with 117824 additions and 1553 deletions

1
.gitignore vendored
View File

@@ -7,6 +7,7 @@
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.idea
.DS_Store
/build
/captures

51
.idea/gradle.xml generated
View File

@@ -1,15 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<compositeConfiguration>
<compositeBuild compositeDefinitionSource="SCRIPT" />
</compositeConfiguration>
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/foudations" />
<option value="$PROJECT_DIR$/foudations/mogo-base-services-apk" />
<option value="$PROJECT_DIR$/foudations/mogo-base-services-sdk" />
<option value="$PROJECT_DIR$/foudations/mogo-commons" />
<option value="$PROJECT_DIR$/foudations/mogo-utils" />
<option value="$PROJECT_DIR$/libraries" />
<option value="$PROJECT_DIR$/libraries/map-amap" />
<option value="$PROJECT_DIR$/libraries/map-autonavi" />
<option value="$PROJECT_DIR$/libraries/mogo-map" />
<option value="$PROJECT_DIR$/libraries/mogo-map-api" />
<option value="$PROJECT_DIR$/main-extensions" />
<option value="$PROJECT_DIR$/main-extensions/mogo-module-main-independent" />
<option value="$PROJECT_DIR$/main-extensions/mogo-module-main-launcher" />
<option value="$PROJECT_DIR$/modules" />
<option value="$PROJECT_DIR$/modules/mogo-module-apps" />
<option value="$PROJECT_DIR$/modules/mogo-module-authorize" />
<option value="$PROJECT_DIR$/modules/mogo-module-back" />
<option value="$PROJECT_DIR$/modules/mogo-module-common" />
<option value="$PROJECT_DIR$/modules/mogo-module-event-panel" />
<option value="$PROJECT_DIR$/modules/mogo-module-event-panel-noop" />
<option value="$PROJECT_DIR$/modules/mogo-module-extensions" />
<option value="$PROJECT_DIR$/modules/mogo-module-gps-simulator" />
<option value="$PROJECT_DIR$/modules/mogo-module-gps-simulator-debug" />
<option value="$PROJECT_DIR$/modules/mogo-module-gps-simulator-noop" />
<option value="$PROJECT_DIR$/modules/mogo-module-left-panel" />
<option value="$PROJECT_DIR$/modules/mogo-module-left-panel-noop" />
<option value="$PROJECT_DIR$/modules/mogo-module-main" />
<option value="$PROJECT_DIR$/modules/mogo-module-map" />
<option value="$PROJECT_DIR$/modules/mogo-module-media" />
<option value="$PROJECT_DIR$/modules/mogo-module-obu" />
<option value="$PROJECT_DIR$/modules/mogo-module-search" />
<option value="$PROJECT_DIR$/modules/mogo-module-service" />
<option value="$PROJECT_DIR$/modules/mogo-module-share" />
<option value="$PROJECT_DIR$/modules/mogo-module-splash" />
<option value="$PROJECT_DIR$/modules/mogo-module-splash-noop" />
<option value="$PROJECT_DIR$/modules/mogo-module-v2x" />
<option value="$PROJECT_DIR$/services" />
<option value="$PROJECT_DIR$/services/mogo-service" />
<option value="$PROJECT_DIR$/services/mogo-service-api" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="testRunner" value="PLATFORM" />
</GradleProjectSettings>
</option>
</component>

12
.idea/misc.xml generated
View File

@@ -1,14 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeSettings">
<configurations>
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
</configurations>
<component name="ASMPluginConfiguration">
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

35
app/README.md Normal file
View File

@@ -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 功能引入

View File

@@ -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.zx[1,99], y[0, 99], z[0, 99])")
}
if (num2 < 0 || num2 > 99){
throw new GradleException("版本号必须定义为 x.y.zx[1,99], y[0, 99], z[0, 99])")
}
if (num3 < 0 || num3 > 99){
throw new GradleException("版本号必须定义为 x.y.zx[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.zx[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"
}
}
}

1
app/functions/README.md Normal file
View File

@@ -0,0 +1 @@
# 不同渠道依赖的实现不一样需要各个渠道都去依赖各自需要的实现渠道太多导致build.gradle 文件臃肿可以通过分gradle文件方式减少臃肿

View File

@@ -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')
}
}

View File

@@ -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')
}
}

View File

@@ -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')
}
}

View File

@@ -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')
}
}

View File

@@ -0,0 +1,7 @@
// 基于socket长链的push推送
project.dependencies {
implementation rootProject.ext.dependencies.modulepushbase
launcherImplementation rootProject.ext.dependencies.modulepush
independentImplementation rootProject.ext.dependencies.modulepushnoop
}

BIN
app/libs/persistentlib.jar Normal file

Binary file not shown.

352
app/proguard-rules.pro vendored
View File

@@ -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 <methods>;
}
#这个主要是在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 <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(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 <fields>;
}
# 对于带有回调函数的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 <fields>;
}
-keep class kotlin.Metadata { *; }
-dontwarn kotlin.*
-dontwarn kotlin.**
-keepclassmembers class **$WhenMappings {
<fields>;
}
-keepclassmembers class kotlin.Metadata {
public <methods>;
}
-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.** { <fields>; }
# 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 <fields>;
}
#-----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 {
<init>(...);
}
-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 <methods>;
}
-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.* <methods>;
}
# 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.* <methods>; }
-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 <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# And if you use AsyncExecutor:
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(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.**{*;}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="android.uid.system"
package="com.mogo.launcher">
</manifest>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="android.uid.system"
package="com.mogo.launcher">
</manifest>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mogo.launcher">
<application
android:name=".MogoApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_shell_name"
android:supportsRtl="true"
android:theme="@style/AppTheme.App"
tools:replace="android:label">
<!-- 高德地图 -->
<meta-data
tools:replace="android:value"
android:name="com.amap.api.v2.apikey"
android:value="1c3fbc5f5e183619ffb1e7bc01e6751f" />
</application>
<uses-permission android:name="android.permission.WAKE_LOCK" />
</manifest>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mogo.launcher">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:name=".MogoApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_shell_name"
android:supportsRtl="true"
android:theme="@style/AppTheme.App"
tools:replace="android:label">
<!-- <provider-->
<!-- android:name="com.mogo.module.navi.cp.AddressContentProvider"-->
<!-- android:authorities="com.zhidao.auto.personal.provider"-->
<!-- android:enabled="true"-->
<!-- android:exported="true" />-->
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="a36b9f7b086fa3951bb35338a5a06dd3"
tools:replace="android:value" />
<!-- 高德地图 -->
</application>
</manifest>

View File

@@ -1,16 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mogo.launcher">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:name=".MogoApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:icon="@drawable/ic_launcher"
android:label="@string/app_shell_name"
android:supportsRtl="true"
android:theme="@style/AppTheme.App">
android:theme="@style/AppTheme.App"
tools:replace="android:label">
<!--保活用-->
<service
android:name="com.zhidao.boot.persistent.lib.PersistentAliveService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.zhidao.boot.persistent.lib.action" />
</intent-filter>
</service>
<activity
android:name="com.zhidao.boot.persistent.lib.PersistentAliveActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
</application>
</manifest>

View File

@@ -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;
* <p>
* 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 );
}
}

View File

@@ -1,34 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@@ -1,170 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_shell_name">蘑菇知途</string>
</resources>

View File

@@ -3,4 +3,7 @@
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
<color name="app_window_background">#1C1C1C</color>
</resources>

View File

@@ -1,3 +1,3 @@
<resources>
<string name="app_name">MogoLauncher</string>
<string name="app_shell_name">蘑菇出行</string>
</resources>

View File

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

View File

@@ -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'
}
}
}
}

View File

@@ -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}",
]
}

View File

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

View File

@@ -0,0 +1,7 @@
## 基实现功能
基础服务apk实现对应功能位置上报、长连接、passport
位置上报com.zhidao.locationinfo
长链com.zhidao.socketservice
passport

View File

@@ -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()

View File

@@ -0,0 +1,3 @@
GROUP=com.mogo.base
POM_ARTIFACT_ID=services-apk
VERSION_CODE=1

View File

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

View File

@@ -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() );
}
}
}

View File

@@ -0,0 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.base.services.apk">
/
</manifest>

View File

@@ -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" );
}
}

View File

@@ -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" );
}
}

View File

@@ -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
* <p>
* 长链实现:基于 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;
}
/**
* 管理消息分发
* <p>
* key - msgType
*/
private Map< Integer, List< IMogoOnMessageListener > > mListeners = new ConcurrentHashMap<>();
/**
* 管理消息回执
* <p>
* 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 ) {
}
}

View File

@@ -1,4 +1,4 @@
package com.mogo.launcher;
package com.mogo.base.services.apk;
import org.junit.Test;

View File

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

View File

@@ -0,0 +1,3 @@
## sdk实现功能
脱离基础服务apk实现对应功能位置上报、长连接、passport

View File

@@ -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()

View File

@@ -0,0 +1,2 @@
#-----MogoBaseServiceSdk-----
-keep class com.mogo.base.services.locationinfo.MogoLocationSource.*{*;}

View File

@@ -0,0 +1,3 @@
GROUP=com.mogo.base
POM_ARTIFACT_ID=services-sdk
VERSION_CODE=1

View File

@@ -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.*{*;}

View File

@@ -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() );
}
}
}

View File

@@ -0,0 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.base.services">
/
</manifest>

View File

@@ -0,0 +1,16 @@
package com.mogo.base.services;
public
/**
* @author congtaowang
* @since 2020/7/23
*
* 描述
*/
interface BaseServicesConstants {
/**
* 建立长链的通道ID
*/
String SOCKET_CHANNEL_ID = "dataCrawler";
}

View File

@@ -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" );
}
}

View File

@@ -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;
}
}

View File

@@ -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 );
}
}

View File

@@ -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;
}
/**
* 管理消息分发
* <p>
* key - msgType
*/
private Map< Integer, List< IMogoOnMessageListener > > mListeners = new ConcurrentHashMap<>();
/**
* 管理消息回执
* <p>
* 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 ) {
}
}

View File

@@ -0,0 +1,4 @@
com.mogo.commons.mvp
com.mogo.commons.debug
com.mogo.commons.voice
com.mogo.commons.data

View File

@@ -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()

View File

@@ -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

View File

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

View File

@@ -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

View File

@@ -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() );
}
}

View File

@@ -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
* <p>
* 埋点
*/
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 );
}
}

View File

@@ -0,0 +1,240 @@
package com.mogo.commons.debug;
import com.mogo.utils.logger.Logger;
/**
* @author congtaowang
* @since 2019-12-23
* <p>
* 各个模块递调试信息控制接口
* <p>
* 注:该类已经不再是简单的调试配置,已经涉及到功能逻辑了 囧
*/
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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,19 @@
package com.mogo.commons.mvp;
import android.content.Context;
/**
* @author congtaowang
* @since 2019-12-23
* <p>
* mvp的view接口
*/
public interface IView {
/**
* 获取上下文
*
* @return
*/
Context getContext();
}

View File

@@ -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
* <p>
* 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;
}
}

View File

@@ -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
* <p>
* 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;
}
}

View File

@@ -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
* <p>
* mvp fragment
*/
public abstract class MvpFragment<V extends IView, P extends Presenter<V>> 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 extends View> 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;
}
}

View File

@@ -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
* <p>
* 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;
}
}

View File

@@ -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";
/**
* signsalt
*/
String SIGN_PREFIX = "JGjZx6";
}

View File

@@ -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 );
}
}

View File

@@ -0,0 +1,39 @@
package com.mogo.commons.network;
import java.util.HashMap;
import java.util.Map;
/**
* @author congtaowang
* @since 2020-01-02
* <p>
* 缓存当前经纬度位置,便于接口请求
*/
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;
}
}

View File

@@ -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 );
}
}
}

View File

@@ -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;
}
}

View File

@@ -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";
}

View File

@@ -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() {
}
}

View File

@@ -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;
}
}

View File

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

View File

@@ -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;
* <p>
* 语音助手通信助手
*/
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 );
}
}
}

View File

@@ -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 ){}
}

View File

@@ -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 {
}

View File

@@ -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;
}
}

View File

@@ -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 {
}

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="90dp" />
<gradient
android:angle="270"
android:endColor="#F2161616"
android:startColor="#F2161616" />
</shape>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/module_commons_toast_bkg"
android:orientation="vertical">
<TextView
android:id="@+id/module_commons_toast_msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/module_commons_toast_marginLeft"
android:layout_marginTop="@dimen/module_commons_toast_marginTop"
android:layout_marginRight="@dimen/module_commons_toast_marginRight"
android:layout_marginBottom="@dimen/module_commons_toast_marginBottom"
android:ellipsize="end"
android:gravity="center"
android:maxWidth="@dimen/module_commons_toast_maxWidth"
android:maxLength="20"
android:maxLines="1"
android:minWidth="@dimen/module_commons_toast_minWidth"
android:textColor="#FFFF"
android:textSize="@dimen/module_commons_toast_textSize"
tools:text="测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试" />
</LinearLayout>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="module_commons_toast_marginLeft">50px</dimen>
<dimen name="module_commons_toast_marginRight">50px</dimen>
<dimen name="module_commons_toast_marginTop">32px</dimen>
<dimen name="module_commons_toast_marginBottom">32px</dimen>
<dimen name="module_commons_toast_textSize">40px</dimen>
<dimen name="module_commons_toast_minWidth">698px</dimen>
<dimen name="module_commons_toast_maxWidth">900px</dimen>
<dimen name="module_commons_toast_y_offset">130px</dimen>
</resources>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="module_commons_toast_marginLeft">30px</dimen>
<dimen name="module_commons_toast_marginRight">30px</dimen>
<dimen name="module_commons_toast_marginTop">16px</dimen>
<dimen name="module_commons_toast_marginBottom">16px</dimen>
<dimen name="module_commons_toast_textSize">22px</dimen>
<dimen name="module_commons_toast_minWidth">371px</dimen>
<dimen name="module_commons_toast_maxWidth">500px</dimen>
<dimen name="module_commons_toast_y_offset">72px</dimen>
</resources>

View File

@@ -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()

View File

@@ -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

View File

@@ -0,0 +1,3 @@
GROUP=com.mogo.commons
POM_ARTIFACT_ID=mogo-utils
VERSION_CODE=1

Some files were not shown because too many files have changed in this diff Show More