Files
peko-android/app/src/main/java/com/yizhuan/habu/application/XChatApplication.java
2023-11-15 23:08:51 +08:00

562 lines
21 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.yizhuan.habu.application;
import static com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment.CUSTOM_MSG_HEADER_TYPE_OPEN_ROOM_NOTI;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.graphics.Color;
import android.net.http.HttpResponseCache;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import androidx.multidex.MultiDex;
import com.bumptech.glide.request.target.ViewTarget;
import com.coorchice.library.utils.LogUtils;
import com.facebook.stetho.Stetho;
import com.hjq.toast.ToastUtils;
import com.mob.MobSDK;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.NotificationFoldStyle;
import com.netease.nimlib.sdk.SDKOptions;
import com.netease.nimlib.sdk.StatusBarNotificationConfig;
import com.netease.nimlib.sdk.mixpush.MixPushConfig;
import com.netease.nimlib.sdk.mixpush.NIMPushClient;
import com.netease.nimlib.sdk.msg.MessageNotifierCustomization;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.util.NIMUtil;
import com.opensource.svgaplayer.SVGAParser;
import com.orhanobut.logger.AndroidLogAdapter;
import com.orhanobut.logger.Logger;
import com.scwang.smartrefresh.header.MaterialHeader;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.footer.ClassicsFooter;
import com.tencent.vasdolly.helper.ChannelReaderUtil;
import com.yizhuan.habu.AgentActivity;
import com.yizhuan.habu.BuildConfig;
import com.yizhuan.habu.NimMiddleActivity;
import com.yizhuan.habu.R;
import com.yizhuan.habu.common.app.ActivityStack;
import com.yizhuan.habu.common.util.AppLifeCycleHelper;
import com.yizhuan.habu.module_hall.HallDataManager;
import com.yizhuan.habu.radish.wallet.RadishWalletManager;
import com.yizhuan.habu.utils.PushMessageHandler;
import com.yizhuan.xchat_android_constants.XChatConstants;
import com.yizhuan.xchat_android_core.Constants;
import com.yizhuan.xchat_android_core.DemoCache;
import com.yizhuan.xchat_android_core.UriProvider;
import com.yizhuan.xchat_android_core.auth.AuthModel;
import com.yizhuan.xchat_android_core.bean.response.ServiceResult;
import com.yizhuan.xchat_android_core.channel.ChannelModel;
import com.yizhuan.xchat_android_core.family.model.FamilyModel;
import com.yizhuan.xchat_android_core.gift.GiftModel;
import com.yizhuan.xchat_android_core.im.custom.bean.CustomAttachment;
import com.yizhuan.xchat_android_core.im.custom.bean.OpenSignInAttachment;
import com.yizhuan.xchat_android_core.initial.InitialModel;
import com.yizhuan.xchat_android_core.interceptor.NoParamsInterceptor;
import com.yizhuan.xchat_android_core.interceptor.ParamsInterceptor;
import com.yizhuan.xchat_android_core.interceptor.TimeSyncInterceptor;
import com.yizhuan.xchat_android_core.manager.IMMessageManager;
import com.yizhuan.xchat_android_core.manager.IMSystemMsgManager;
import com.yizhuan.xchat_android_core.market_verify.MarketVerifyModel;
import com.yizhuan.xchat_android_core.mentoring_relationship.model.MentoringRelationshipModel;
import com.yizhuan.xchat_android_core.pay.PayModel;
import com.yizhuan.xchat_android_core.public_chat_hall.model.PublicChatHallModel;
import com.yizhuan.xchat_android_core.radish.RadishModel;
import com.yizhuan.xchat_android_core.radish.signin.bean.ImNotice;
import com.yizhuan.xchat_android_core.room.face.DynamicFaceModel;
import com.yizhuan.xchat_android_core.user.UserModel;
import com.yizhuan.xchat_android_core.user.event.NeedCompleteInfoEvent;
import com.yizhuan.xchat_android_core.utils.SharedPreferenceUtils;
import com.yizhuan.xchat_android_core.utils.net.ServerException;
import com.yizhuan.xchat_android_library.common.application.BaseApp;
import com.yizhuan.xchat_android_library.common.application.Env;
import com.yizhuan.xchat_android_library.common.file.FileHelper;
import com.yizhuan.xchat_android_library.net.rxnet.RxNet;
import com.yizhuan.xchat_android_library.net.rxnet.converter.GsonConverterPlugins;
import com.yizhuan.xchat_android_library.utils.AppMetaDataUtil;
import com.yizhuan.xchat_android_library.utils.AppUtils;
import com.yizhuan.xchat_android_library.utils.DeviceUuidFactory;
import com.yizhuan.xchat_android_library.utils.ResUtil;
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
import com.yizhuan.xchat_android_library.utils.SystemUtils;
import com.yizhuan.xchat_android_library.utils.VersionUtil;
import com.yizhuan.xchat_android_library.utils.codec.MD5Utils;
import com.yizhuan.xchat_android_library.utils.config.BasicConfig;
import org.greenrobot.eventbus.EventBus;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import io.reactivex.plugins.RxJavaPlugins;
import io.realm.Realm;
import io.realm.RealmConfiguration;
/**
* @author chenran
* @date 2017/2/11
*/
public class XChatApplication extends BaseApp {
public static final String TAG = "XChatApplication";
public static Application gContext;
private static final MessageNotifierCustomization messageNotifierCustomization = new MessageNotifierCustomization() {
@Override
public String makeNotifyContent(String nick, IMMessage message) {
if (message.getMsgType() == MsgTypeEnum.custom) {
CustomAttachment customAttachment = (CustomAttachment) message.getAttachment();
if (customAttachment.getFirst() == CUSTOM_MSG_HEADER_TYPE_OPEN_ROOM_NOTI) {
return message.getFromNick();
} else if (customAttachment instanceof OpenSignInAttachment) {
return getContentFromOpenSignIn(customAttachment);
}
}
// 采用SDK默认文案
return ResUtil.getString(R.string.erban_application_xchatapplication_01);
}
@Override
public String makeTicker(String nick, IMMessage message) {
if (message.getMsgType() == MsgTypeEnum.custom) {
CustomAttachment customAttachment = (CustomAttachment) message.getAttachment();
if (customAttachment != null) {
if (customAttachment.getFirst() == CUSTOM_MSG_HEADER_TYPE_OPEN_ROOM_NOTI) {
return message.getFromNick();
} else if (customAttachment instanceof OpenSignInAttachment) {
return getContentFromOpenSignIn(customAttachment);
}
}
}
// 采用SDK默认文案
return ResUtil.getString(R.string.erban_application_xchatapplication_02);
}
private String getContentFromOpenSignIn(CustomAttachment attachment) {
String result = null;
if (attachment instanceof OpenSignInAttachment) {
ImNotice notice = ((OpenSignInAttachment) attachment).getImNotice();
if (notice != null) {
result = notice.getContent();
}
}
if (TextUtils.isEmpty(result)) {
result = ResUtil.getString(R.string.erban_application_xchatapplication_03);
}
return result;
}
@Override
public String makeRevokeMsgTip(String s, IMMessage imMessage) {
return null;
}
@Override
public String makeCategory(IMMessage message) {
return null;
}
};
private static XChatApplication instance;
//生命周期监听
private static AppLifeCycleHelper lifeCycleHelper;
public static ActivityStack gStack = new ActivityStack();
private static boolean isInitOtherSDK = false;
//static 代码段可以防止内存泄露
static {
SmartRefreshLayout.setDefaultRefreshHeaderCreater(
(context, layout) -> {
layout.setEnableHeaderTranslationContent(false);
MaterialHeader materialHeader = new MaterialHeader(context);
materialHeader.setShowBezierWave(false);
return materialHeader;
});
SmartRefreshLayout.setDefaultRefreshFooterCreater(
(context, layout) -> new ClassicsFooter(context).setDrawableSize(20));
}
public static XChatApplication instance() {
return instance;
}
public static void initOtherSDK() {
if (isInitOtherSDK) return;
isInitOtherSDK = true;
Context context = BasicConfig.INSTANCE.getAppContext();
Application application = (Application) context.getApplicationContext();
// 初始化 sp
long startTime = System.currentTimeMillis();
String channel = "";
channel = ChannelReaderUtil.getChannel(instance);
if (TextUtils.isEmpty(channel)) {
channel = Constants.GOOGLE;
}
BasicConfig.INSTANCE.setOriginalChannel(channel);
BasicConfig.INSTANCE.setChannel(channel);
initEnv();
//延迟初始化云信
NIMClient.init(context, null, options());
//logger 配置
Logger.addLogAdapter(new AndroidLogAdapter() {
@Override
public boolean isLoggable(int priority, String tag) {
return BuildConfig.DEBUG;
}
});
ToastUtils.init(application);
if (inMainProcess(context)) {
DemoCache.saveLaunchCount();
// 注册自定义推送消息处理,这个是可选项
NIMPushClient.registerMixPushMessageHandler(new PushMessageHandler());
RxJavaPlugins.setErrorHandler(throwable -> {
if (BuildConfig.DEBUG) {
Log.e(TAG, "the subscribe() method default error handler", throwable);
}
});
//需要完善资料错误码全局处理
GsonConverterPlugins.setResultHandler(result -> {
if (result instanceof ServiceResult<?>) {
ServiceResult<?> serviceResult = (ServiceResult<?>) result;
if (serviceResult.getCode() == ServiceResult.CODE_NEED_COMPLETE_USER_INFO) {
SingleToastUtil.showToast(serviceResult.getMessage());
EventBus.getDefault().post(new NeedCompleteInfoEvent());
throw new ServerException(serviceResult.getMessage(), serviceResult.getCode());
}
}
return null;
});
GsonConverterPlugins.lockdown();
//fixed: Glide Exception:"You must not call setTag() on a view Glide is targeting"
ViewTarget.setTagId(R.id.tag_glide);
initStetho(context);
init(channel);
//生命周期监听
if (lifeCycleHelper == null) {
lifeCycleHelper = new AppLifeCycleHelper();
}
registerActivityLifecycleCallback(lifeCycleHelper);
initLinkedMe();
MobSDK.init(context);
MobSDK.submitPolicyGrantResult(true);
}
LogUtils.d("init time = " + (System.currentTimeMillis() - startTime) + "ms");
}
public static void registerActivityLifecycleCallback(Application.ActivityLifecycleCallbacks callbacks) {
((Application) BasicConfig.INSTANCE.getAppContext().getApplicationContext()).registerActivityLifecycleCallbacks(callbacks);
}
/**
* 初始化linkedMe
*/
private static void initLinkedMe() {
MobSDK.init(instance, "32fd2f8457880", "ef796ca85e8cd95a76929663de133214");
// MobLink.setRestoreSceneListener(new RestoreSceneListener() {
// @Override
// public Class<? extends Activity> willRestoreScene(Scene scene) {
// return AgentActivity.class;
// }
//
// @Override
// public void completeRestore(Scene scene) {
// }
//
// @Override
// public void notFoundScene(Scene scene) {
// }
// });
}
private static void initEnv() {
//首先初始化环境
Env.initEnv(BuildConfig.BUILD_TYPE, BuildConfig.DEBUG);
//切换生产坏境和测试环境 true/测试环境 false/生产环境
BasicConfig.INSTANCE.setDebuggable(Env.isDebug());
BasicConfig.INSTANCE.setRootDir(Constants.ERBAN_DIR_NAME);
BasicConfig.INSTANCE.setLogDir(Constants.LOG_DIR);
BasicConfig.INSTANCE.setConfigDir(Constants.CONFIG_DIR);
BasicConfig.INSTANCE.setVoiceDir(Constants.VOICE_DIR);
BasicConfig.INSTANCE.setCacheDir(Constants.CACHE_DIR);
BasicConfig.INSTANCE.setImageDir(Constants.IMAGE_CACHE_DIR);
}
/**
* 云信配置
*
* @return
*/
public static SDKOptions options() {
SDKOptions options = new SDKOptions();
options.disableAwake = true;
options.asyncInitSDK = true;
// options.customPushContentType = "";
if (isDebug()) {
options.checkManifestConfig = true;
}
// 如果将新消息通知提醒托管给 SDK 完成,需要添加以下配置。否则无需设置。
StatusBarNotificationConfig config = new StatusBarNotificationConfig();
// 点击通知栏跳转到该Activity
config.notificationEntrance = NimMiddleActivity.class;
// config.notificationSmallIconId = R.drawable.icon_msg_normal;
// 呼吸灯配置
config.ledARGB = Color.GREEN;
config.ledOnMs = 1000;
config.ledOffMs = 1500;
config.notificationFoldStyle = NotificationFoldStyle.CONTACT;
// 通知铃声的uri字符串
config.notificationSound = "android.resource://com.netease.nim.demo/raw/msg";
options.statusBarNotificationConfig = config;
// 定制通知栏提醒文案可选如果不定制将采用SDK默认文案
options.messageNotifierCustomization = messageNotifierCustomization;
options.appKey = Constants.nimAppKey;
// 配置保存图片文件log 等数据的目录
// 如果 options 中没有设置这个值SDK 会使用下面代码示例中的位置作为 SDK 的数据目录。
// 该目录目前包含 log, file, image, audio, video, thumb 这6个目录。
// 如果第三方 APP 需要缓存清理功能, 清理这个目录下面个子目录的内容即可。
String sdkPath = null;
try {
sdkPath = FileHelper.getRootCacheDir().getAbsolutePath() + "/nim";
} catch (ArrayIndexOutOfBoundsException e) {
}
options.sdkStorageRootPath = sdkPath;
// 配置是否需要预下载附件缩略图,默认为 true
options.preloadAttach = true;
// 配置附件缩略图的尺寸大小。表示向服务器请求缩略图文件的大小
// 该值一般应根据屏幕尺寸来确定, 默认值为 Screen.width / 2
int widthPixels = BasicConfig.INSTANCE.getAppContext().getResources().getDisplayMetrics().widthPixels;
options.thumbnailSize = widthPixels / 2;
// // save cache留做切换账号备用
DemoCache.setNotificationConfig(config);
MixPushConfig mixPushConfig = new MixPushConfig();
options.mixPushConfig = mixPushConfig;
return options;
}
/**
* 判断当前进程是否主进程
*
* @param context
* @return
*/
private static boolean inMainProcess(Context context) {
String packageName = context.getPackageName();
String processName = NIMUtil.getProcessName(context);
return packageName.equals(processName);
}
/**
* 初始化RxNet
*
* @param context
* @param url
*/
@SuppressLint("CheckResult")
public static void initRxNet(Context context, String url) {
Map<String, String> httpParams = new ConcurrentHashMap<>();
httpParams.put("os", "android");
httpParams.put("osVersion", Build.VERSION.RELEASE);
httpParams.put("app", XChatConstants.APP_MARK);
httpParams.put("ispType", String.valueOf(SystemUtils.getIspType(context)));
httpParams.put("netType", String.valueOf(SystemUtils.getNetworkType(context)));
httpParams.put("model", SystemUtils.getPhoneModel());
httpParams.put("appVersion", VersionUtil.getLocalName(context));
httpParams.put("appVersionCode", String.valueOf(AppUtils.getVersionCode(context)));
httpParams.put("deviceId", DeviceUuidFactory.getDeviceId(context));
httpParams.put("androidId", MD5Utils.getMD5String(Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID)));
httpParams.put("channel", AppMetaDataUtil.getChannelID());
RxNet.init(context)
.debug(BuildConfig.DEBUG)
.setBaseUrl(url)
.addInterceptors(new ParamsInterceptor(httpParams))
.addInterceptors(new NoParamsInterceptor())//注意:拦截器的添加顺序,请求的拦截顺序
.addInterceptors(new TimeSyncInterceptor())
.certificates()
.build();
//单例的model 初始化
initModel();
}
private static void init(String channel) {
initNimUIKit();
UriProvider.initUri(BuildConfig.BASE_URL_DEBUG, BuildConfig.BASE_URL_STAGING, BuildConfig.BASE_URL_RELEASE);
SVGAParser.Companion.shareParser().init(BasicConfig.INSTANCE.getAppContext());
try {
/** svga动画缓存路径 */
String cacheDirPath = FileHelper.getRootCacheDir().getAbsolutePath();
File cacheFie = new File(cacheDirPath, "cacheDir");
HttpResponseCache.install(cacheFie, 1024 * 1024 * 128);
} catch (IOException e) {
Log.e(TAG, "HttpResponseCache install error :" + e.getMessage());
}
initRxNet(BasicConfig.INSTANCE.getAppContext(), UriProvider.JAVA_WEB_URL);
/**
* 使用到realm 数据库,这里配置数据库 这里必须先于模块初始化前进行初始化配置
*/
Realm.init(BasicConfig.INSTANCE.getAppContext());
RealmConfiguration config = new RealmConfiguration.Builder()
.name("accompany.realm")
.deleteRealmIfMigrationNeeded()
.build();
Realm.setDefaultConfiguration(config);
LogUtil.i(TAG, channel);
}
/**
* 一些单例的 model
*/
private static void initModel() {
DynamicFaceModel.get().init();
PayModel.get();
UserModel.get();
//ui层的萝卜钱包
RadishWalletManager.get();
//model层的
RadishModel.get();
IMMessageManager.get().init();
IMSystemMsgManager.get().init();
FamilyModel.Instance();
AuthModel.get();
ChannelModel.get();
MarketVerifyModel.get();
GiftModel.get();
PublicChatHallModel.get();
// 模厅
HallDataManager.get().application();
// 师徒
MentoringRelationshipModel.get();
//全局处理
GlobalHandleManager.get().init();
InitialModel.get().init(true).subscribe();
//上报平台初始化
ReportManager.get().init();
}
private static void initNimUIKit() {
// 初始化
NimUIKit.init(BasicConfig.INSTANCE.getAppContext());
}
/**
* debug 环境 受到实验室模式影响
*/
public static boolean isDebug() {
return Env.isDebug();
}
/**
* 是否是真实的debug的环境 不受实验室模式影响
*
* @return
*/
public static boolean isRealDebug() {
return Env.isRealDebug();
}
/**
* 用户没同意隐私协议之前,啥也不干!!
*/
@Override
public void onCreate() {
super.onCreate();
instance = this;
BaseApp.init(this);
BasicConfig.INSTANCE.setAppContext(this.getApplicationContext());
SharedPreferenceUtils.init(this);
ResUtil.init(this);
initOtherSDK();
initContext(this);
//首次启动事件
HashMap<String, Object> map = new HashMap<>(2);
map.put(IReportConstants.MODULE, IReportConstants.PEKO_ACTIVATE);
ReportManager.get().reportEvent(IReportConstants.ACTIVATE_FIRST, map);
}
/**
* 初始化Application实例
*/
public void initContext(Application application) {
gContext = application;
}
/**
* @return 获取Application实例
*/
public static Application getApplication() {
return gContext;
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(base);
}
@Override
public void onTerminate() {
super.onTerminate();
GlobalHandleManager.get().unInit();
if (lifeCycleHelper != null) {
unregisterActivityLifecycleCallbacks(lifeCycleHelper);
}
}
/**
* 初始化Stetho网络调试
*/
private static void initStetho(Context context) {
if (Env.isDebug()) {
Stetho.initialize(
Stetho.newInitializerBuilder(context)
.enableDumpapp(Stetho.defaultDumperPluginsProvider(context))
.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(context))
.build()
);
}
}
}