diff --git a/app/build.gradle b/app/build.gradle index 68f370a242..004a1ca41c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -289,12 +289,15 @@ dependencies { // implementation(project(':module_setting_compose')) { // exclude group: 'androidx.swiperefreshlayout' // } - implementation(project(':module_core_feature')){ + implementation(project(':module_core_feature')) { exclude group: 'androidx.swiperefreshlayout' } implementation(project(':module_feedback')) { exclude group: 'androidx.swiperefreshlayout' } + implementation(project(':module_sensors_data')) { + exclude group: 'androidx.swiperefreshlayout' + } // 默认不接入光能模块,提高编译速度 // debugImplementation(project(':module_energy')) { // exclude group: 'androidx.swiperefreshlayout' diff --git a/app/src/main/java/com/gh/common/util/DataUtils.java b/app/src/main/java/com/gh/common/util/DataUtils.java index 550cc4e8b1..a735db8c1e 100644 --- a/app/src/main/java/com/gh/common/util/DataUtils.java +++ b/app/src/main/java/com/gh/common/util/DataUtils.java @@ -9,19 +9,23 @@ import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.Log; +import com.alibaba.android.arouter.launcher.ARouter; import com.gh.base.GlobalActivityManager; import com.gh.gamecenter.BuildConfig; import com.gh.gamecenter.common.base.activity.BaseActivity; import com.gh.gamecenter.common.constant.Constants; +import com.gh.gamecenter.common.constant.RouteConsts; import com.gh.gamecenter.common.exposure.meta.MetaUtil; import com.gh.gamecenter.common.retrofit.BiResponse; import com.gh.gamecenter.core.AppExecutor; +import com.gh.gamecenter.core.provider.ISensorsProvider; import com.gh.gamecenter.core.utils.GsonUtils; import com.gh.gamecenter.core.utils.MtaHelper; import com.gh.gamecenter.core.utils.SPUtils; import com.gh.gamecenter.core.utils.SentryHelper; import com.gh.gamecenter.login.entity.IdCardEntity; import com.gh.gamecenter.login.entity.UserInfoEntity; +import com.gh.gamecenter.login.user.UserManager; import com.gh.gamecenter.provider.GhContentProvider; import com.gh.gamecenter.retrofit.RetrofitManager; import com.gh.gid.GidCallback; @@ -114,6 +118,11 @@ public class DataUtils { String originalGid = HaloApp.getInstance().getGid(); HaloApp.getInstance().setGid(gid); + ISensorsProvider sensorsProvider = (ISensorsProvider) ARouter.getInstance().build(RouteConsts.provider.sensors).navigation(); + if (sensorsProvider != null) { + sensorsProvider.setGid(gid); + } + // 避免重复调用 if (!TextUtils.isEmpty(gid) && !gid.equals(originalGid)) { GameSubstituteRepositoryHelper.updateSubstitutableGames(); diff --git a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt index c4601bca04..5b6aa05795 100644 --- a/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt +++ b/app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt @@ -17,6 +17,7 @@ import androidx.core.app.ActivityCompat import androidx.viewpager.widget.PagerAdapter import androidx.viewpager.widget.ViewPager import com.alibaba.android.arouter.facade.annotation.Route +import com.alibaba.android.arouter.launcher.ARouter import com.g00fy2.versioncompare.Version import com.gh.common.constant.Config import com.gh.common.dialog.NewPrivacyPolicyDialogFragment @@ -31,6 +32,8 @@ import com.gh.gamecenter.common.constant.Constants import com.gh.gamecenter.common.constant.RouteConsts import com.gh.gamecenter.common.tracker.TrackerLogger import com.gh.gamecenter.common.utils.* +import com.gh.gamecenter.core.provider.ISensorsProvider +import com.gh.gamecenter.core.provider.IWebProvider import com.gh.gamecenter.core.runOnIoThread import com.gh.gamecenter.core.utils.* import com.gh.gamecenter.entity.PrivacyPolicyEntity @@ -273,6 +276,10 @@ class SplashScreenActivity : BaseActivity() { private fun doFlavorInit() { HaloApp.getInstance().flavorProvider.init(HaloApp.getInstance(), this) + + val sensorsProvider = + ARouter.getInstance().build(RouteConsts.provider.sensors).navigation() as? ISensorsProvider + sensorsProvider?.init(HaloApp.getInstance(), HaloApp.getInstance().channel) } private fun getGitLogString(): String { diff --git a/build.gradle b/build.gradle index 1afd4ed465..be77d21c53 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ buildscript { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // 使用了 1.2.21 在蓝叠模拟器上无法进入首页? 但是不使用又会出现触发 V3 签名... classpath 'io.github.leon406:AndResGuard-gradle-plugin:1.2.22.6' + classpath 'com.sensorsdata.analytics.android:android-gradle-plugin2:3.5.3' } } diff --git a/dependencies.gradle b/dependencies.gradle index 2045a4fce5..2ddc9c8d44 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -131,4 +131,6 @@ ext { activityComposeVersion = "1.6.0" composeCompilerVersion = "1.3.2" constraintlayoutCompose = "1.0.1" + + sensorsDataVersion = "6.6.3" } \ No newline at end of file diff --git a/module_common/src/main/java/com/gh/gamecenter/common/constant/RouteConsts.kt b/module_common/src/main/java/com/gh/gamecenter/common/constant/RouteConsts.kt index 821f7d6c8c..89069e6975 100644 --- a/module_common/src/main/java/com/gh/gamecenter/common/constant/RouteConsts.kt +++ b/module_common/src/main/java/com/gh/gamecenter/common/constant/RouteConsts.kt @@ -75,6 +75,8 @@ object RouteConsts { const val composeSetting = "/composeSetting/composeSetting" const val vpn = "/vpn/vpn" + + const val sensors = "/sensors/sensors" } } \ No newline at end of file diff --git a/module_core/src/main/java/com/gh/gamecenter/core/provider/ISensorsProvider.kt b/module_core/src/main/java/com/gh/gamecenter/core/provider/ISensorsProvider.kt new file mode 100644 index 0000000000..a3e5c13a5a --- /dev/null +++ b/module_core/src/main/java/com/gh/gamecenter/core/provider/ISensorsProvider.kt @@ -0,0 +1,17 @@ +package com.gh.gamecenter.core.provider + +import android.app.Application +import com.alibaba.android.arouter.facade.template.IProvider +import org.json.JSONObject + +interface ISensorsProvider : IProvider { + fun init(application: Application, channel: String) + + fun login(loginId: String) + + fun logout(loginId: String) + + fun setGid(gid: String) + + fun trackEvent(eventName: String, jsonObject: JSONObject) +} \ No newline at end of file diff --git a/module_login/src/main/java/com/gh/gamecenter/login/user/UserRepository.java b/module_login/src/main/java/com/gh/gamecenter/login/user/UserRepository.java index 71ff2b8375..80cebadf65 100644 --- a/module_login/src/main/java/com/gh/gamecenter/login/user/UserRepository.java +++ b/module_login/src/main/java/com/gh/gamecenter/login/user/UserRepository.java @@ -17,6 +17,7 @@ import androidx.lifecycle.MediatorLiveData; import com.alibaba.android.arouter.launcher.ARouter; import com.gh.gamecenter.common.utils.PackageFlavorHelper; import com.gh.gamecenter.core.provider.IAppProvider; +import com.gh.gamecenter.core.provider.ISensorsProvider; import com.gh.gamecenter.core.provider.IWechatBindHelperProvider; import com.gh.gamecenter.login.HaloApp; import com.gh.gamecenter.login.utils.LoginHelper; @@ -124,6 +125,10 @@ public class UserRepository { } public void logout() { + ISensorsProvider sensorsProvider = (ISensorsProvider) ARouter.getInstance().build(RouteConsts.provider.sensors).navigation(); + if (sensorsProvider != null) { + sensorsProvider.logout(UserManager.getInstance().getUserId()); + } if (UserManager.getInstance().getLoginTokenEntity() != null && "qq".equals(UserManager.getInstance().getLoginTokenEntity().getLoginType())) { @@ -527,6 +532,11 @@ public class UserRepository { appProvider.getFlavorProvider().logEvent("active_register"); } + ISensorsProvider sensorsProvider = (ISensorsProvider) ARouter.getInstance().build(RouteConsts.provider.sensors).navigation(); + if (sensorsProvider != null) { + sensorsProvider.login(UserManager.getInstance().getUserId()); + } + IEnergyTaskProvider energyTaskHelper = (IEnergyTaskProvider) ARouter.getInstance().build(RouteConsts.provider.energyTask).navigation(); if (energyTaskHelper == null) return; diff --git a/module_sensors_data/.gitignore b/module_sensors_data/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/module_sensors_data/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/module_sensors_data/build.gradle b/module_sensors_data/build.gradle new file mode 100644 index 0000000000..392b43d456 --- /dev/null +++ b/module_sensors_data/build.gradle @@ -0,0 +1,56 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' + id 'kotlin-kapt' + id 'com.sensorsdata.analytics.android' +} + +android { + compileSdk rootProject.ext.compileSdkVersion + + defaultConfig { + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + versionCode rootProject.ext.versionCode + versionName rootProject.ext.versionName + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + kapt { + arguments { + arg("AROUTER_MODULE_NAME", project.name) + } + } + + buildTypes { + debug { + manifestPlaceholders.put("SENSORS_SCHEME", "sad821cc0b") + } + + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + manifestPlaceholders.put("SENSORS_SCHEME", "saf547873a") + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} + +dependencies { + kapt "com.alibaba:arouter-compiler:$arouterVersion" + implementation "com.sensorsdata.analytics.android:SensorsAnalyticsSDK:$sensorsDataVersion" + implementation(project(path: ":module_common")) { + exclude group: 'androidx.swiperefreshlayout' + } + + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} \ No newline at end of file diff --git a/module_sensors_data/proguard-rules.pro b/module_sensors_data/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/module_sensors_data/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/module_sensors_data/src/androidTest/java/com/gh/gamecenter/sensorsdata/ExampleInstrumentedTest.java b/module_sensors_data/src/androidTest/java/com/gh/gamecenter/sensorsdata/ExampleInstrumentedTest.java new file mode 100644 index 0000000000..b28062f6c8 --- /dev/null +++ b/module_sensors_data/src/androidTest/java/com/gh/gamecenter/sensorsdata/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.gh.gamecenter.sensorsdata; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.gh.gamecenter.sensorsdata.test", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/module_sensors_data/src/main/AndroidManifest.xml b/module_sensors_data/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..5bb0cfe143 --- /dev/null +++ b/module_sensors_data/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/module_sensors_data/src/main/java/com/gh/gamecenter/sensorsdata/SensorsHelper.kt b/module_sensors_data/src/main/java/com/gh/gamecenter/sensorsdata/SensorsHelper.kt new file mode 100644 index 0000000000..4c12f53a7c --- /dev/null +++ b/module_sensors_data/src/main/java/com/gh/gamecenter/sensorsdata/SensorsHelper.kt @@ -0,0 +1,59 @@ +package com.gh.gamecenter.sensorsdata + +import android.content.Context +import com.gh.gamecenter.common.exposure.meta.MetaUtil +import com.gh.gamecenter.common.utils.EnvHelper +import com.gh.gamecenter.common.utils.PackageFlavorHelper +import com.sensorsdata.analytics.android.sdk.SAConfigOptions +import com.sensorsdata.analytics.android.sdk.SensorsDataAPI +import org.json.JSONException +import org.json.JSONObject + + +object SensorsHelper { + private const val DEV_SA_SERVER_URL = "https://sensors-data-api.ghzs.com/sa?project=default" + private const val SA_SERVER_URL = "https://sensors-data-api.ghzs.com/sa?project=production" + private const val KEY_USER_ID = "mongold_id" + private const val KEY_GID = "g_id" + + @JvmStatic + fun init(context: Context, channel: String) { + // 初始化 + SensorsDataAPI.startWithConfigOptions( + context, + SAConfigOptions(if (PackageFlavorHelper.IS_TEST_FLAVOR) DEV_SA_SERVER_URL else SA_SERVER_URL).apply { + enableLog(EnvHelper.isDevEnv) + }) + + // 设置静态公共属性 + SensorsDataAPI.sharedInstance().registerSuperProperties(JSONObject().apply { + put("channel", channel) + put("jnfj", MetaUtil.getBase64EncodedIMEI()) + put("mac", MetaUtil.getMeta().mac) + }) + } + + @JvmStatic + fun login(loginId: String) { + SensorsDataAPI.sharedInstance().bind(KEY_USER_ID, loginId) + } + + @JvmStatic + fun logout(loginId: String) { + SensorsDataAPI.sharedInstance().unbind(KEY_USER_ID, loginId) + } + + @JvmStatic + fun setGid(gid: String) { + SensorsDataAPI.sharedInstance().bind(KEY_GID, gid) + } + + @JvmStatic + fun track(eventName: String, jsonObject: JSONObject) { + try { + SensorsDataAPI.sharedInstance().track(eventName, jsonObject) + } catch (e: JSONException) { + e.printStackTrace() + } + } +} \ No newline at end of file diff --git a/module_sensors_data/src/main/java/com/gh/gamecenter/sensorsdata/provider/SensorsProviderImpl.kt b/module_sensors_data/src/main/java/com/gh/gamecenter/sensorsdata/provider/SensorsProviderImpl.kt new file mode 100644 index 0000000000..941e44dcb8 --- /dev/null +++ b/module_sensors_data/src/main/java/com/gh/gamecenter/sensorsdata/provider/SensorsProviderImpl.kt @@ -0,0 +1,36 @@ +package com.gh.gamecenter.sensorsdata.provider + +import android.app.Application +import android.content.Context +import com.alibaba.android.arouter.facade.annotation.Route +import com.gh.gamecenter.common.constant.RouteConsts +import com.gh.gamecenter.core.provider.ISensorsProvider +import com.gh.gamecenter.sensorsdata.SensorsHelper +import org.json.JSONObject + +@Route(path = RouteConsts.provider.sensors, name = "SensorsHelper暴露服务") +class SensorsProviderImpl : ISensorsProvider { + override fun init(application: Application, channel: String) { + SensorsHelper.init(application, channel) + } + + override fun init(context: Context?) { + // Do nothing + } + + override fun login(loginId: String) { + SensorsHelper.login(loginId) + } + + override fun logout(loginId: String) { + SensorsHelper.logout(loginId) + } + + override fun setGid(gid: String) { + SensorsHelper.setGid(gid) + } + + override fun trackEvent(eventName: String, jsonObject: JSONObject) { + SensorsHelper.track(eventName, jsonObject) + } +} \ No newline at end of file diff --git a/module_sensors_data/src/test/java/com/gh/gamecenter/sensorsdata/ExampleUnitTest.java b/module_sensors_data/src/test/java/com/gh/gamecenter/sensorsdata/ExampleUnitTest.java new file mode 100644 index 0000000000..b65c40fff7 --- /dev/null +++ b/module_sensors_data/src/test/java/com/gh/gamecenter/sensorsdata/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.gh.gamecenter.sensorsdata; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index d853f02ee3..84a5824a14 100644 --- a/settings.gradle +++ b/settings.gradle @@ -13,4 +13,5 @@ include ':module_feedback' include ':ndownload' include ':module_core_feature' include ':module_lib' -include ':module_vpn' \ No newline at end of file +include ':module_vpn' +include ':module_sensors_data'