feat: 消息推送:接入阿里云消息推送系统—客户端 https://jira.shanqu.cc/browse/GHZS-4941

This commit is contained in:
曾祥俊
2024-03-28 17:58:49 +08:00
parent 6c4d17ab9e
commit d406cba6c2
30 changed files with 809 additions and 12 deletions

View File

@ -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:
@ -156,4 +153,3 @@ oss-upload&send-email:
only:
- dev
- dev-5.33.0
- feat/GHZS-3956

View File

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

View File

@ -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<String> bindAccountSingle = pushProvider.bindAccount(getOAID());
// 绑定标签
Single<String> bindTagSingle = pushProvider.bindTag(mChannel)
.subscribeOn(Schedulers.io());
// 初始化推送
pushProvider
.register(this)
.flatMap((response) -> {
// 绑定别名、标签和账号任意一个流程失败,都不会影响其他流程的执行
Single<String> single = bindAccountSingle
.onErrorReturn((e) -> response)
.zipWith(bindTagSingle.onErrorReturn((e) -> response), (s1, s2) -> response);
if (UserManager.getInstance().isLoggedIn()) {
String userId = UserManager.getInstance().getUserId();
// 绑定别名
Single<String> 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();

View File

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

View File

@ -142,4 +142,6 @@ ext {
qGameAdVersion = "4.520.1390"
blankjUtilCodex = "1.30.4"
acloudPush = "3.8.8.1"
}

1
feature/acloud_push/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

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

View File

@ -0,0 +1,25 @@
-keepclasseswithmembernames class ** {
native <methods>;
}
-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.**

21
feature/acloud_push/proguard-rules.pro vendored Normal file
View File

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

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data
android:name="com.alibaba.app.appkey"
android:value="334173476" />
<meta-data
android:name="com.alibaba.app.appsecret"
android:value="da8eed31bfdf4218a1fee18aed59c3c4" />
<receiver android:name=".ACloudPushReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.sdk.android.push.RECEIVE" />
</intent-filter>
</receiver>
</application>
</manifest>

View File

@ -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<String>) : CommonCallback {
override fun onSuccess(response: String) {
emitter.onSuccess(response)
}
override fun onFailed(errorCode: String, errorMessage: String) {
emitter.onError(ACloudPushException(errorCode, errorMessage))
}
}

View File

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

View File

@ -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<String> {
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<String> {
val pushService = PushServiceFactory.getCloudPushService()
return Single.create {
pushService.bindAccount(
account,
ACloudPushCommonCallback(it)
)
}
}
/**
* 绑定别名
* @param alias 别名
* @return 回调结果
*/
fun bindAlias(alias: String): Single<String> {
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<String> {
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<String> {
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)
}
}
}
}

View File

@ -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<String, String>?) {
}
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<String, String>,
openType: Int,
openActivity: String?,
openUrl: String?
) {
}
}

View File

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

View File

@ -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<String> {
return ACloudPushHelper.register(applicationContext)
}
override fun bindAccount(account: String): Single<String> {
return ACloudPushHelper.bindAccount(account)
}
override fun bindAlias(alias: String): Single<String> {
return ACloudPushHelper.bindAlias(alias)
}
override fun unbindAlias(alias: String): Single<String> {
return ACloudPushHelper.unbindAlias(alias)
}
override fun bindTag(tag: String): Single<String> {
return ACloudPushHelper.bindTag(tag)
}
override fun init(p0: Context?) {}
}

View File

@ -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<ResponseBody>
/**
* 解绑别名
*/
@POST("ali/emas_push/alias/unbind")
@Headers("Content-Type: application/json", "Accept: application/json")
fun unbindAlias(@Body body: RequestBody): Single<ResponseBody>
/**
* 绑定标签
*/
@POST("ali/emas_push/tag/bind")
@Headers("Content-Type: application/json", "Accept: application/json")
fun bindTag(@Body body: RequestBody): Single<ResponseBody>
/**
* 解绑标签
*/
@POST("ali/emas_push/tag/unbind")
@Headers("Content-Type: application/json", "Accept: application/json")
fun unbindTag(@Body body: RequestBody): Single<ResponseBody>
}

View File

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

1
feature/jg_push/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

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

View File

21
feature/jg_push/proguard-rules.pro vendored Normal file
View File

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

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View File

@ -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<String> {
Utils.log("JGPushProviderImpl", "注册推送")
return Single.just("")
}
override fun bindAccount(account: String): Single<String> {
Utils.log("JGPushProviderImpl", "绑定账号: $account")
return Single.just("")
}
override fun bindAlias(alias: String): Single<String> {
Utils.log("JGPushProviderImpl", "绑定别名: $alias")
return Single.just("")
}
override fun unbindAlias(alias: String): Single<String> {
Utils.log("JGPushProviderImpl", "解绑别名: $alias")
return Single.just("")
}
override fun bindTag(tag: String): Single<String> {
Utils.log("JGPushProviderImpl", "绑定标签: $tag")
return Single.just("")
}
override fun init(p0: Context?) {}
}

View File

@ -119,6 +119,8 @@ object RouteConsts {
const val qGame = "/qGame/qGame"
const val push = "/push/push"
const val realName = "/realName/realName"
}

View File

@ -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<String>
/**
* 绑定账号
* @param account 账号
* @return 回调结果
*/
fun bindAccount(account: String): Single<String>
/**
* 绑定别名
* @param alias 别名
* @return 回调结果
*/
fun bindAlias(alias: String): Single<String>
/**
* 解绑别名
* @param alias 别名
* @return 回调结果
*/
fun unbindAlias(alias: String): Single<String>
/**
* 绑定标签
* @param tag 标签
* @return 回调结果
*/
fun bindTag(tag: String): Single<String>
}

View File

@ -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<UserInfoEntity> userInfoResponse(final LoginTag loginTag) {
return new Response<UserInfoEntity>() {
@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) {

View File

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

View File

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

View File

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