diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8adc9161ce..8907046ee7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -72,7 +72,6 @@ android_build: only: - dev - dev-5.33.0 - - feat/GHZS-3956 # 代码检查 sonarqube_analysis: @@ -104,7 +103,6 @@ sonarqube_analysis: only: - dev - dev-5.33.0 - - feat/GHZS-3956 ## 发送简易检测结果报告 send_sonar_report: @@ -123,7 +121,6 @@ send_sonar_report: only: - dev - dev-5.33.0 - - feat/GHZS-3956 oss-upload&send-email: tags: @@ -155,5 +152,4 @@ oss-upload&send-email: - /usr/local/bin/python /ci-android-mail-jira-comment.py only: - dev - - dev-5.33.0 - - feat/GHZS-3956 \ No newline at end of file + - dev-5.33.0 \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index cb87bbb70c..03e03b020d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -412,6 +412,13 @@ dependencies { exclude group: 'androidx.swiperefreshlayout' } internalImplementation(project(':module_internal_test')) + + // 根据BUILD_PUSH_TYPE决定使用哪个推送SDK,目前默认使用阿里云推送 + def pushProject = findProperty('BUILD_PUSH_TYPE') == 'jg' + ? project(':feature:jg_push') : project(':feature:acloud_push') + implementation(pushProject) { + exclude group: 'androidx.swiperefreshlayout' + } } File propFile = file('sign.properties') diff --git a/app/src/main/java/com/halo/assistant/HaloApp.java b/app/src/main/java/com/halo/assistant/HaloApp.java index efe1555812..441daffbbd 100644 --- a/app/src/main/java/com/halo/assistant/HaloApp.java +++ b/app/src/main/java/com/halo/assistant/HaloApp.java @@ -1,5 +1,6 @@ package com.halo.assistant; +import android.annotation.SuppressLint; import android.app.Application; import android.content.Context; import android.content.Intent; @@ -50,6 +51,7 @@ import com.gh.gamecenter.BuildConfig; import com.gh.gamecenter.Injection; import com.gh.gamecenter.common.constant.Config; 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.image.EmptyDecoder; import com.gh.gamecenter.common.tracker.Tracker; @@ -63,9 +65,12 @@ import com.gh.gamecenter.common.utils.SensorsBridge; import com.gh.gamecenter.core.AppExecutor; import com.gh.gamecenter.core.iinterface.IApplication; import com.gh.gamecenter.core.provider.IFlavorProvider; +import com.gh.gamecenter.core.provider.IPushProvider; import com.gh.gamecenter.core.utils.DisplayUtils; import com.gh.gamecenter.core.utils.GsonUtils; import com.gh.gamecenter.core.utils.SPUtils; +import com.gh.gamecenter.entity.SubjectRecommendEntity; +import com.gh.gamecenter.login.user.UserManager; import com.gh.gamecenter.login.user.UserRepository; import com.gh.gamecenter.oaid.OAIDHelper; import com.gh.gamecenter.packagehelper.PackageRepository; @@ -89,7 +94,10 @@ import java.lang.reflect.Method; import java.util.List; import java.util.ServiceLoader; +import io.reactivex.Single; +import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.plugins.RxJavaPlugins; +import io.reactivex.schedulers.Schedulers; import tv.danmaku.ijk.media.exo2.Exo2PlayerManager; import tv.danmaku.ijk.media.exo2.ExoPlayerCacheManager; @@ -252,6 +260,9 @@ public class HaloApp extends MultiDexApplication { deviceRamSize = DeviceUtils.getTotalRamSizeOfDevice(this); mChannel = mFlavorProvider.getChannelStr(this); + // 初始化阿里云推送 + ExtensionsKt.doOnMainProcessOnly(this, this::initPushEngine); + // 异步初始化 SP SPUtils.getString(""); }); @@ -314,6 +325,8 @@ public class HaloApp extends MultiDexApplication { MetaUtil.INSTANCE.refreshMeta(); SensorsBridge.INSTANCE.setOAID(s); + registerPushEngine(); + // 上报设备安装事件 if (isNewForThisVersion) { final LunchType launchType = getLaunchType(); @@ -435,6 +448,61 @@ public class HaloApp extends MultiDexApplication { this.registerReceiver(skipReceiver, skipFilter); } + /** + * 初始化推送 + */ + private void initPushEngine() { + IPushProvider pushProvider = (IPushProvider) ARouter + .getInstance() + .build(RouteConsts.provider.push) + .navigation(); + pushProvider.initialize(this); + } + + /** + * 同意隐私政策后,注册推送功能 + */ + @SuppressLint("CheckResult") + private void registerPushEngine() { + IPushProvider pushProvider = (IPushProvider) ARouter + .getInstance() + .build(RouteConsts.provider.push) + .navigation(); + + // 绑定账号 + Single bindAccountSingle = pushProvider.bindAccount(getOAID()); + + // 绑定标签 + Single bindTagSingle = pushProvider.bindTag(mChannel) + .subscribeOn(Schedulers.io()); + + // 初始化推送 + pushProvider + .register(this) + .flatMap((response) -> { + // 绑定别名、标签和账号任意一个流程失败,都不会影响其他流程的执行 + Single single = bindAccountSingle + .onErrorReturn((e) -> response) + .zipWith(bindTagSingle.onErrorReturn((e) -> response), (s1, s2) -> response); + if (UserManager.getInstance().isLoggedIn()) { + String userId = UserManager.getInstance().getUserId(); + // 绑定别名 + Single bindAliasSingle = pushProvider + .bindAlias(userId) + .subscribeOn(Schedulers.io()); + single = single.zipWith(bindAliasSingle.onErrorReturn((e) -> response), (s1, s2) -> response); + } + return single; + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + s -> Utils.log("IPushProvider->init push succeed, response: " + s + ",channel: " + getChannel()), + e -> Utils.log("IPushProvider->init push failed, error: " + e + ", channel: " + getChannel()) + ); + + } + private void initPackageChangesReceiver() { InstallAndUninstallReceiver receiver = new InstallAndUninstallReceiver(); IntentFilter intentFilter = new IntentFilter(); diff --git a/build.gradle b/build.gradle index 12a56d8cb4..bcc0ff95af 100644 --- a/build.gradle +++ b/build.gradle @@ -39,6 +39,13 @@ allprojects { maven { url 'https://maven.aliyun.com/nexus/content/repositories/releases/' } maven { url 'https://artifact.bytedance.com/repository/Volcengine/'} maven { url 'https://artifact.bytedance.com/repository/pangle' } + maven { + url 'http://maven.aliyun.com/nexus/content/repositories/releases/' + name 'aliyun' + allowInsecureProtocol true + } + // 配置HMS Core SDK的Maven仓地址。 + maven { url 'https://developer.huawei.com/repo/' } } } diff --git a/dependencies.gradle b/dependencies.gradle index 259a48bc97..e7c0f8f58e 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -142,4 +142,6 @@ ext { qGameAdVersion = "4.520.1390" blankjUtilCodex = "1.30.4" + + acloudPush = "3.8.8.1" } \ No newline at end of file diff --git a/feature/acloud_push/.gitignore b/feature/acloud_push/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/feature/acloud_push/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/acloud_push/build.gradle b/feature/acloud_push/build.gradle new file mode 100644 index 0000000000..b98bb479a8 --- /dev/null +++ b/feature/acloud_push/build.gradle @@ -0,0 +1,46 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' + id 'kotlin-kapt' +} + +android { + namespace 'com.gh.gamecenter.acloud.push' + compileSdk 34 + + defaultConfig { + minSdk 24 + + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } + + kapt { + arguments { + arg("AROUTER_MODULE_NAME", project.name) + } + } +} + +dependencies { + implementation(project(path: ":module_common")) { + exclude group: 'androidx.swiperefreshlayout' + } + + implementation "com.aliyun.ams:alicloud-android-push:$acloudPush" + + kapt "com.alibaba:arouter-compiler:$arouterVersion" +} \ No newline at end of file diff --git a/feature/acloud_push/consumer-rules.pro b/feature/acloud_push/consumer-rules.pro new file mode 100644 index 0000000000..f84f9aa028 --- /dev/null +++ b/feature/acloud_push/consumer-rules.pro @@ -0,0 +1,25 @@ +-keepclasseswithmembernames class ** { + native ; +} +-keepattributes Signature +-keep class sun.misc.Unsafe { *; } +-keep class com.taobao.** {*;} +-keep class com.alibaba.** {*;} +-keep class com.alipay.** {*;} +-keep class com.ut.** {*;} +-keep class com.ta.** {*;} +-keep class anet.**{*;} +-keep class anetwork.**{*;} +-keep class org.android.spdy.**{*;} +-keep class org.android.agoo.**{*;} +-keep class android.os.**{*;} +-keep class org.json.**{*;} +-dontwarn com.taobao.** +-dontwarn com.alibaba.** +-dontwarn com.alipay.** +-dontwarn anet.** +-dontwarn org.android.spdy.** +-dontwarn org.android.agoo.** +-dontwarn anetwork.** +-dontwarn com.ut.** +-dontwarn com.ta.** \ No newline at end of file diff --git a/feature/acloud_push/proguard-rules.pro b/feature/acloud_push/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/feature/acloud_push/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/feature/acloud_push/src/main/AndroidManifest.xml b/feature/acloud_push/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..a56be9da5e --- /dev/null +++ b/feature/acloud_push/src/main/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushCommonCallback.kt b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushCommonCallback.kt new file mode 100644 index 0000000000..37dcfb7277 --- /dev/null +++ b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushCommonCallback.kt @@ -0,0 +1,14 @@ +package com.gh.gamecenter.acloud.push + +import com.alibaba.sdk.android.push.CommonCallback +import io.reactivex.SingleEmitter + +class ACloudPushCommonCallback(private val emitter: SingleEmitter) : CommonCallback { + override fun onSuccess(response: String) { + emitter.onSuccess(response) + } + + override fun onFailed(errorCode: String, errorMessage: String) { + emitter.onError(ACloudPushException(errorCode, errorMessage)) + } +} \ No newline at end of file diff --git a/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushException.kt b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushException.kt new file mode 100644 index 0000000000..9e3a199589 --- /dev/null +++ b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushException.kt @@ -0,0 +1,7 @@ +package com.gh.gamecenter.acloud.push + +class ACloudPushException(val errorCode: String, errorMessage: String) : Throwable(errorMessage) { + override fun toString(): String { + return "errorCode: $errorCode, message: $message" + } +} \ No newline at end of file diff --git a/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushHelper.kt b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushHelper.kt new file mode 100644 index 0000000000..edee32fd8f --- /dev/null +++ b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushHelper.kt @@ -0,0 +1,173 @@ +package com.gh.gamecenter.acloud.push + +import android.app.NotificationChannel +import android.app.NotificationManager +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.net.Uri +import android.os.Build +import com.alibaba.android.arouter.launcher.ARouter +import com.alibaba.sdk.android.push.CloudPushService +import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory +import com.gh.gamecenter.acloud.push.retrofit.RetrofitManager +import com.gh.gamecenter.common.BuildConfig +import com.gh.gamecenter.common.constant.RouteConsts +import com.gh.gamecenter.common.utils.toJson +import com.gh.gamecenter.common.utils.toRequestBody +import com.gh.gamecenter.core.provider.IAppProvider +import com.gh.gamecenter.core.utils.GsonUtils +import com.lightgame.utils.Utils +import io.reactivex.Single +import okhttp3.ResponseBody + +object ACloudPushHelper { + + private const val PUSH_CHANNEL = "光环channel" + + /** + * 初始化云推送通道 + * @param applicationContext + */ + fun init(applicationContext: Context) { + // 初始化云推送通道 + PushServiceFactory.init(applicationContext) + // Android 8.0+ 初始化NotificationChannel + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val notificationManager = + applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager? + // 用户可以看到的通知渠道的名字。 + val appProvider = ARouter + .getInstance() + .build(RouteConsts.provider.app) + .navigation() as IAppProvider + val name: CharSequence = appProvider.getAppName() + val importance = NotificationManager.IMPORTANCE_HIGH + val channel = NotificationChannel(PUSH_CHANNEL, name, importance) + // 设置通知出现时的闪灯(如果Android设备支持的话)。 + channel.enableLights(true) + channel.lightColor = Color.RED + // 设置通知出现时的震动(如果Android设备支持的话)。 + channel.enableVibration(true) + channel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400) + // 创建通知渠道。 + notificationManager!!.createNotificationChannel(channel) + } + } + + /** + * 注册阿里云推送 + * @param applicationContext 上下文 + * @return 回调结果 + */ + fun register(applicationContext: Context): Single { + val pushService = PushServiceFactory.getCloudPushService() + if (BuildConfig.DEBUG) { + pushService.setLogLevel(CloudPushService.LOG_DEBUG) + } + + return Single.create { + pushService.register(applicationContext, ACloudPushCommonCallback(it)) + } + } + + /** + * 获取设备ID + * @return 设备ID + */ + fun getDeviceId(): String { + val pushService = PushServiceFactory.getCloudPushService() + return pushService.deviceId ?: "" + } + + /** + * 绑定账号 + * @param account 账号 + * @return 回调结果 + */ + fun bindAccount(account: String): Single { + val pushService = PushServiceFactory.getCloudPushService() + return Single.create { + pushService.bindAccount( + account, + ACloudPushCommonCallback(it) + ) + } + } + + /** + * 绑定别名 + * @param alias 别名 + * @return 回调结果 + */ + fun bindAlias(alias: String): Single { + val data = mapOf( + "device_id" to getDeviceId(), + "user_id" to alias + ) + return RetrofitManager + .getInstance() + .newApi + .bindAlias(data.toRequestBody()) + .map { alias } + } + + /** + * 解绑别名 + * @param alias 别名 + * @return 回调结果 + */ + fun unbindAlias(alias: String): Single { + val data = mapOf( + "device_id" to getDeviceId(), + "user_id" to alias + ) + return RetrofitManager + .getInstance() + .newApi + .unbindAlias(data.toRequestBody()) + .map { alias } + } + + /** + * 绑定标签 + * @param tag 标签 + * @return 回调结果 + */ + fun bindTag(tag: String): Single { + val data = mapOf( + "device_id" to getDeviceId(), + "channel" to tag + ) + return RetrofitManager + .getInstance() + .newApi + .bindTag(data.toRequestBody()) + .map { tag } + } + + /** + * 处理通知栏点击事件 + * @param context 上下文 + * @param title 通知栏标题 + * @param summary 通知栏描述 + * @param extraMap json格式的附加参数 + */ + internal fun handleNotificationOpened(context: Context, title: String, summary: String, extraMap: String?) { + Utils.log("ACloudPush->onNotificationOpened->title: $title, summary: $summary, extraMap: $extraMap") + if (!extraMap.isNullOrEmpty()) { + val map = GsonUtils.fromJson(extraMap, Map::class.java) + val url = map["url"] as String? + if (!url.isNullOrEmpty()) { + val intent = Intent().apply { + data = Uri.parse(url) + action = Intent.ACTION_VIEW + addCategory(Intent.CATEGORY_DEFAULT) + addCategory(Intent.CATEGORY_BROWSABLE) + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } + context.startActivity(intent) + } + } + } +} \ No newline at end of file diff --git a/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushReceiver.kt b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushReceiver.kt new file mode 100644 index 0000000000..c4fa006ded --- /dev/null +++ b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/ACloudPushReceiver.kt @@ -0,0 +1,43 @@ +package com.gh.gamecenter.acloud.push + +import android.content.Context +import android.content.Intent +import android.net.Uri +import com.alibaba.sdk.android.push.MessageReceiver +import com.alibaba.sdk.android.push.notification.CPushMessage +import com.gh.gamecenter.core.utils.GsonUtils +import com.lightgame.utils.Utils + +class ACloudPushReceiver : MessageReceiver() { + + override fun onNotificationOpened(context: Context, title: String, summary: String, extraMap: String?) { + ACloudPushHelper.handleNotificationOpened(context, title, summary, extraMap) + } + + override fun onNotificationRemoved(context: Context, messageId: String) { + + } + + override fun onNotification(context: Context, title: String, summary: String, extraMap: MutableMap?) { + + } + + override fun onMessage(context: Context, cPushMessage: CPushMessage) { + + } + + override fun onNotificationClickedWithNoAction(context: Context, title: String, summary: String, extraMap: String) { + } + + override fun onNotificationReceivedInApp( + context: Context, + title: String, + summary: String, + extraMap: MutableMap, + openType: Int, + openActivity: String?, + openUrl: String? + ) { + + } +} \ No newline at end of file diff --git a/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/HaloApp.kt b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/HaloApp.kt new file mode 100644 index 0000000000..835bb31481 --- /dev/null +++ b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/HaloApp.kt @@ -0,0 +1,43 @@ +package com.gh.gamecenter.acloud.push + +import android.app.Application +import android.content.res.Configuration +import com.gh.gamecenter.core.iinterface.IApplication +import com.google.auto.service.AutoService + +@AutoService(IApplication::class) +class HaloApp : IApplication { + + override fun attachBaseContext() { + // Do nothing + } + + override fun onCreate(application: Application) { + mApp = application + } + + override fun onLowMemory() { + // Do nothing + } + + override fun onTerminate() { + // Do nothing + } + + override fun onTrimMemory(level: Int) { + // Do nothing + } + + override fun onConfigurationChanged(newConfig: Configuration) { + // Do nothing + } + + companion object { + private lateinit var mApp: Application + + @JvmStatic + fun getInstance(): Application { + return mApp + } + } +} \ No newline at end of file diff --git a/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/provider/ACloudPushProviderImpl.kt b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/provider/ACloudPushProviderImpl.kt new file mode 100644 index 0000000000..097d674c10 --- /dev/null +++ b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/provider/ACloudPushProviderImpl.kt @@ -0,0 +1,41 @@ +package com.gh.gamecenter.acloud.push.provider + +import android.content.Context +import com.alibaba.android.arouter.facade.annotation.Route +import com.gh.gamecenter.acloud.push.ACloudPushHelper +import com.gh.gamecenter.common.constant.RouteConsts +import com.gh.gamecenter.core.provider.IPushProvider +import io.reactivex.Single + +/** + * 阿里云推送服务提供者类 + */ +@Route(path = RouteConsts.provider.push, name = "阿里云推送暴露服务") +class ACloudPushProviderImpl : IPushProvider { + + override fun initialize(applicationContext: Context) { + ACloudPushHelper.init(applicationContext) + } + + override fun register(applicationContext: Context): Single { + return ACloudPushHelper.register(applicationContext) + } + + override fun bindAccount(account: String): Single { + return ACloudPushHelper.bindAccount(account) + } + + override fun bindAlias(alias: String): Single { + return ACloudPushHelper.bindAlias(alias) + } + + override fun unbindAlias(alias: String): Single { + return ACloudPushHelper.unbindAlias(alias) + } + + override fun bindTag(tag: String): Single { + return ACloudPushHelper.bindTag(tag) + } + + override fun init(p0: Context?) {} +} \ No newline at end of file diff --git a/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/retrofit/ApiService.kt b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/retrofit/ApiService.kt new file mode 100644 index 0000000000..5955aced84 --- /dev/null +++ b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/retrofit/ApiService.kt @@ -0,0 +1,37 @@ +package com.gh.gamecenter.acloud.push.retrofit + +import io.reactivex.Observable +import io.reactivex.Single +import okhttp3.RequestBody +import okhttp3.ResponseBody +import retrofit2.http.* + +interface ApiService { + /** + * 绑定别名 + */ + @POST("ali/emas_push/alias/bind") + @Headers("Content-Type: application/json", "Accept: application/json") + fun bindAlias(@Body body: RequestBody): Single + + /** + * 解绑别名 + */ + @POST("ali/emas_push/alias/unbind") + @Headers("Content-Type: application/json", "Accept: application/json") + fun unbindAlias(@Body body: RequestBody): Single + + /** + * 绑定标签 + */ + @POST("ali/emas_push/tag/bind") + @Headers("Content-Type: application/json", "Accept: application/json") + fun bindTag(@Body body: RequestBody): Single + + /** + * 解绑标签 + */ + @POST("ali/emas_push/tag/unbind") + @Headers("Content-Type: application/json", "Accept: application/json") + fun unbindTag(@Body body: RequestBody): Single +} \ No newline at end of file diff --git a/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/retrofit/RetrofitManager.kt b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/retrofit/RetrofitManager.kt new file mode 100644 index 0000000000..cb999a5643 --- /dev/null +++ b/feature/acloud_push/src/main/java/com/gh/gamecenter/acloud/push/retrofit/RetrofitManager.kt @@ -0,0 +1,22 @@ +package com.gh.gamecenter.acloud.push.retrofit + +import com.gh.gamecenter.common.retrofit.BaseRetrofitManager +import com.gh.gamecenter.common.utils.EnvHelper.getHost +import com.gh.gamecenter.common.utils.EnvHelper.getNewHost +import com.gh.gamecenter.core.utils.SingletonHolder +import com.gh.gamecenter.acloud.push.HaloApp + +class RetrofitManager private constructor() : BaseRetrofitManager() { + + val api: ApiService + val newApi: ApiService + + init { + val context = HaloApp.getInstance().applicationContext + val okHttpNormalConfig = getOkHttpConfig(context, 0, 2) + api = provideService(okHttpNormalConfig, getHost(), ApiService::class.java) + newApi = provideService(okHttpNormalConfig, getNewHost(), ApiService::class.java) + } + + companion object : SingletonHolder(::RetrofitManager) +} \ No newline at end of file diff --git a/feature/jg_push/.gitignore b/feature/jg_push/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/feature/jg_push/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/jg_push/build.gradle b/feature/jg_push/build.gradle new file mode 100644 index 0000000000..6f2a61b8e6 --- /dev/null +++ b/feature/jg_push/build.gradle @@ -0,0 +1,45 @@ +plugins { + id 'com.android.library' + id 'org.jetbrains.kotlin.android' + id 'kotlin-kapt' +} + +android { + namespace 'com.gh.gamecenter.jg.push' + compileSdk 34 + + defaultConfig { + minSdk 24 + + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } + + kapt { + arguments { + arg("AROUTER_MODULE_NAME", project.name) + } + } +} + +dependencies { + + implementation(project(path: ":module_common")) { + exclude group: 'androidx.swiperefreshlayout' + } + + kapt "com.alibaba:arouter-compiler:$arouterVersion" +} \ No newline at end of file diff --git a/feature/jg_push/consumer-rules.pro b/feature/jg_push/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/feature/jg_push/proguard-rules.pro b/feature/jg_push/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/feature/jg_push/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/feature/jg_push/src/main/AndroidManifest.xml b/feature/jg_push/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..a5918e68ab --- /dev/null +++ b/feature/jg_push/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/feature/jg_push/src/main/java/com/gh/gamecenter/jg/push/provider/JGPushProviderImpl.kt b/feature/jg_push/src/main/java/com/gh/gamecenter/jg/push/provider/JGPushProviderImpl.kt new file mode 100644 index 0000000000..7b37dca5dc --- /dev/null +++ b/feature/jg_push/src/main/java/com/gh/gamecenter/jg/push/provider/JGPushProviderImpl.kt @@ -0,0 +1,45 @@ +package com.gh.gamecenter.jg.push.provider + +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.IPushProvider +import com.lightgame.utils.Utils +import io.reactivex.Single + +/** + * 极光推送服务提供者类 + */ +@Route(path = RouteConsts.provider.push, name = "极光推送暴露服务") +class JGPushProviderImpl : IPushProvider { + override fun initialize(applicationContext: Context) { + Utils.log("JGPushProviderImpl", "初始化推送") + } + + override fun register(applicationContext: Context): Single { + Utils.log("JGPushProviderImpl", "注册推送") + return Single.just("") + } + + override fun bindAccount(account: String): Single { + Utils.log("JGPushProviderImpl", "绑定账号: $account") + return Single.just("") + } + + override fun bindAlias(alias: String): Single { + Utils.log("JGPushProviderImpl", "绑定别名: $alias") + return Single.just("") + } + + override fun unbindAlias(alias: String): Single { + Utils.log("JGPushProviderImpl", "解绑别名: $alias") + return Single.just("") + } + + override fun bindTag(tag: String): Single { + Utils.log("JGPushProviderImpl", "绑定标签: $tag") + return Single.just("") + } + + override fun init(p0: Context?) {} +} \ 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 a60339a9d3..65985cda51 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 @@ -119,6 +119,8 @@ object RouteConsts { const val qGame = "/qGame/qGame" + const val push = "/push/push" + const val realName = "/realName/realName" } diff --git a/module_core/src/main/java/com/gh/gamecenter/core/provider/IPushProvider.kt b/module_core/src/main/java/com/gh/gamecenter/core/provider/IPushProvider.kt new file mode 100644 index 0000000000..0418b2698a --- /dev/null +++ b/module_core/src/main/java/com/gh/gamecenter/core/provider/IPushProvider.kt @@ -0,0 +1,49 @@ +package com.gh.gamecenter.core.provider + +import android.content.Context +import com.alibaba.android.arouter.facade.template.IProvider +import io.reactivex.Single + +interface IPushProvider : IProvider { + + /** + * 同意隐私政策前初始化推送功能 + * @param applicationContext 上下文 + */ + fun initialize(applicationContext: Context) + + /** + * 同意隐私政策后注册推送功能 + * @param applicationContext 上下文 + * @return 回调结果 + */ + fun register(applicationContext: Context): Single + + /** + * 绑定账号 + * @param account 账号 + * @return 回调结果 + */ + fun bindAccount(account: String): Single + + /** + * 绑定别名 + * @param alias 别名 + * @return 回调结果 + */ + fun bindAlias(alias: String): Single + + /** + * 解绑别名 + * @param alias 别名 + * @return 回调结果 + */ + fun unbindAlias(alias: String): Single + + /** + * 绑定标签 + * @param tag 标签 + * @return 回调结果 + */ + fun bindTag(tag: String): Single +} \ 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 5da555da36..6cddf57145 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 @@ -26,6 +26,7 @@ import com.gh.gamecenter.common.utils.DeviceUtils; import com.gh.gamecenter.common.utils.EnvHelper; import com.gh.gamecenter.common.utils.PackageFlavorHelper; import com.gh.gamecenter.common.utils.SensorsBridge; +import com.gh.gamecenter.core.provider.IPushProvider; import com.gh.gamecenter.core.provider.IAppProvider; import com.gh.gamecenter.core.provider.IDataUtilsProvider; import com.gh.gamecenter.core.provider.IDownloadManagerProvider; @@ -118,8 +119,10 @@ public class UserRepository { logout(); } + @SuppressLint("CheckResult") public void logout() { - SensorsBridge.logout(UserManager.getInstance().getUserId()); + String userId = UserManager.getInstance().getUserId(); + SensorsBridge.logout(userId); if (UserManager.getInstance().getLoginTokenEntity() != null && "qq".equals(UserManager.getInstance().getLoginTokenEntity().getLoginType())) { @@ -128,6 +131,19 @@ public class UserRepository { UserManager.getInstance().logout(); + if (!TextUtils.isEmpty(userId)) { + // 退出登录后推送解绑别名 + IPushProvider pushProvider = (IPushProvider) ARouter + .getInstance() + .build(RouteConsts.provider.push) + .navigation(); + pushProvider + .unbindAlias(userId) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe((s) -> {}, (e) -> {}); + } + mLoginObsResponseUserInfo.postValue(null); mObservableLoginToken.postValue(null); @@ -493,6 +509,7 @@ public class UserRepository { private Response userInfoResponse(final LoginTag loginTag) { return new Response() { + @SuppressLint("CheckResult") @Override public void onResponse(UserInfoEntity response) { super.onResponse(response); @@ -513,6 +530,17 @@ public class UserRepository { if (messageUnreadRepository != null) { messageUnreadRepository.loadMessageUnreadData(); } + + // 登录成功后推送绑定别名 + IPushProvider pushProvider = (IPushProvider) ARouter + .getInstance() + .build(RouteConsts.provider.push) + .navigation(); + pushProvider + .bindAlias(response.getUserId()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe((s) -> {}, (e) -> {}); } if (UserManager.getInstance().getLoginTokenEntity() != null) { diff --git a/scripts/build_with_simple_backup.sh b/scripts/build_with_simple_backup.sh index e7a22d34d9..84ae4085ed 100755 --- a/scripts/build_with_simple_backup.sh +++ b/scripts/build_with_simple_backup.sh @@ -27,11 +27,13 @@ fi BUILD_VARIANT_ENV=publish BUILD_VARIANT_REGION=cn BUILD_APK_CHANNEL_NAME=标准正式包 +BUILD_PUSH_TYPE=ac BUILD_WITH_INIT_GRADLE=true # 添加 -t 指定编译环境,可选值:t: 头条 k: 快手 g: 广点通 # 添加 -r 指定区域,可选值: cn: 中国大陆 gat: 港澳台 -while getopts "t:r:" arg +# 添加 -p 指定推送类型 可选值: jg: 极光推送 ac: 阿里云推送 +while getopts "t:r:p:" arg do case ${arg} in t) @@ -60,14 +62,22 @@ do ;; esac ;; + p) + case $OPTARG in + jg) BUILD_PUSH_TYPE=jg + ;; + *) BUILD_PUSH_TYPE=ac + ;; + esac + ;; esac done # 不存在指令时打普通包 if [ $BUILD_WITH_INIT_GRADLE == false ]; then - ./gradlew assemble${BUILD_VARIANT_ENV}${BUILD_VARIANT_REGION^}Release + ./gradlew assemble${BUILD_VARIANT_ENV}${BUILD_VARIANT_REGION^}Release -PBUILD_PUSH_TYPE=$BUILD_PUSH_TYPE else - ./gradlew assemble${BUILD_VARIANT_ENV}${BUILD_VARIANT_REGION^}Release -I init.gradle + ./gradlew assemble${BUILD_VARIANT_ENV}${BUILD_VARIANT_REGION^}Release -I init.gradle -PBUILD_PUSH_TYPE=$BUILD_PUSH_TYPE fi mkdir -p release-app/${versionName}_${versionCode} diff --git a/scripts/jenkins_build.sh b/scripts/jenkins_build.sh index 0561999fbb..64409e26db 100755 --- a/scripts/jenkins_build.sh +++ b/scripts/jenkins_build.sh @@ -23,10 +23,12 @@ sed -i 's/buildConfigField "long", "BUILD_TIME", "0"/buildConfigField "long", "B git log --pretty=format:'%s' --max-count=20 --no-merges > app/src/main/assets/gitlog.txt BUILD_VARIANT_REGION=cn +BUILD_PUSH_TYPE=ac # 添加 -c 代表启用 compose setting 模块 # 添加 -r 指定区域,可选值: cn: 中国大陆 gat: 港澳台 -while getopts "cr:" arg +# 添加 -p 指定推送类型 可选值: jg: 极光推送 ac: 阿里云推送 +while getopts "cr:p:" arg do case ${arg} in c) @@ -39,10 +41,19 @@ do *) BUILD_VARIANT_REGION=cn ;; esac + ;; + p) + case $OPTARG in + jg) BUILD_PUSH_TYPE=jg + ;; + *) BUILD_PUSH_TYPE=ac + ;; + esac + ;; esac done -./gradlew resguardInternal${BUILD_VARIANT_REGION^}Release -I ${post_init_script} +./gradlew resguardInternal${BUILD_VARIANT_REGION^}Release -I ${post_init_script} -PBUILD_PUSH_TYPE=${BUILD_PUSH_TYPE} mv app/build/outputs/apk/internal${BUILD_VARIANT_REGION^}/release/app-internal-${BUILD_VARIANT_REGION}-release.apk app/build/tmp/${version}-${versionCode}-test-${build_time}.apk git checkout app/build.gradle @@ -66,4 +77,4 @@ if [[ $1 == "dev"* ]]; then curl -F "file=@${apkFile};type=application/octet-stream" -F "changelog=@./changelog.log;type=application/octet-stream" "${uploadUrl}" rm changelog.log fi -fi \ No newline at end of file +fi diff --git a/settings.gradle b/settings.gradle index f4932c5c6d..350265eba7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -25,3 +25,5 @@ include ':feature:new_feedback' include ':feature:qq_game' include ':feature:realname-window' include ':module_internal_test' +include ':feature:jg_push' +include ':feature:acloud_push'