feat: 消息推送:接入阿里云消息推送系统—客户端 https://jira.shanqu.cc/browse/GHZS-4941
This commit is contained in:
@ -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
|
||||
@ -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')
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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/' }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
1
feature/acloud_push/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
||||
46
feature/acloud_push/build.gradle
Normal file
46
feature/acloud_push/build.gradle
Normal 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"
|
||||
}
|
||||
25
feature/acloud_push/consumer-rules.pro
Normal file
25
feature/acloud_push/consumer-rules.pro
Normal 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
21
feature/acloud_push/proguard-rules.pro
vendored
Normal 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
|
||||
26
feature/acloud_push/src/main/AndroidManifest.xml
Normal file
26
feature/acloud_push/src/main/AndroidManifest.xml
Normal 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>
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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?
|
||||
) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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?) {}
|
||||
}
|
||||
@ -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>
|
||||
}
|
||||
@ -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
1
feature/jg_push/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
||||
45
feature/jg_push/build.gradle
Normal file
45
feature/jg_push/build.gradle
Normal 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"
|
||||
}
|
||||
0
feature/jg_push/consumer-rules.pro
Normal file
0
feature/jg_push/consumer-rules.pro
Normal file
21
feature/jg_push/proguard-rules.pro
vendored
Normal file
21
feature/jg_push/proguard-rules.pro
vendored
Normal 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
|
||||
4
feature/jg_push/src/main/AndroidManifest.xml
Normal file
4
feature/jg_push/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
||||
@ -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?) {}
|
||||
}
|
||||
@ -119,6 +119,8 @@ object RouteConsts {
|
||||
|
||||
const val qGame = "/qGame/qGame"
|
||||
|
||||
const val push = "/push/push"
|
||||
|
||||
const val realName = "/realName/realName"
|
||||
}
|
||||
|
||||
|
||||
@ -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>
|
||||
}
|
||||
@ -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) {
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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'
|
||||
|
||||
Reference in New Issue
Block a user