package com.yizhuan.erban.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.hjq.toast.ToastUtils; import com.mob.MobSDK; import com.mob.moblink.MobLink; import com.mob.moblink.RestoreSceneListener; import com.mob.moblink.Scene; 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.erban.AgentActivity; import com.yizhuan.erban.BuildConfig; import com.yizhuan.erban.NimMiddleActivity; import com.yizhuan.erban.R; import com.yizhuan.erban.common.app.ActivityStack; import com.yizhuan.erban.common.util.AppLifeCycleHelper; import com.yizhuan.erban.module_hall.HallDataManager; import com.yizhuan.erban.other.activity.SplashActivity; import com.yizhuan.erban.radish.wallet.RadishWalletManager; import com.yizhuan.erban.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.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.Locale; 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; } }; 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); 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, "36b91eeac7469", "63ec0702513aca17e20615dd5dfdc03f"); MobLink.setRestoreSceneListener(new RestoreSceneListener() { @Override public Class 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 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())//注意:拦截器的添加顺序,请求的拦截顺序 .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动画缓存路径 */ File cacheDir = new File(BasicConfig.INSTANCE.getAppContext().getApplicationContext().getExternalCacheDir(), "http"); if (!cacheDir.exists()) cacheDir.mkdirs(); HttpResponseCache.install(cacheDir, 1024 * 1024 * 128); } catch (IOException e) { Log.e(TAG, "testtest", e); } 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); boolean isShowPrivacyAgreement = (boolean) SharedPreferenceUtils.get(SplashActivity.SHOW_PRIVACY_AGREEMENT, true); if (!isShowPrivacyAgreement) { initOtherSDK(); } initContext(this); //首次启动事件 HashMap 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); } } }