package com.netease.nim.uikit;
import android.app.Activity;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.netease.nim.uikit.cache.DataCacheManager;
import com.netease.nim.uikit.cache.TeamDataCache;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nim.uikit.common.util.storage.StorageType;
import com.netease.nim.uikit.common.util.storage.StorageUtil;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.netease.nim.uikit.contact.ContactEventListener;
import com.netease.nim.uikit.contact.ContactProvider;
import com.netease.nim.uikit.contact_selector.activity.ContactSelectActivity;
import com.netease.nim.uikit.custom.DefalutContactEventListener;
import com.netease.nim.uikit.custom.DefalutP2PSessionCustomization;
import com.netease.nim.uikit.custom.DefalutTeamSessionCustomization;
import com.netease.nim.uikit.custom.DefalutUserInfoProvider;
import com.netease.nim.uikit.custom.DefaultContactProvider;
import com.netease.nim.uikit.session.SessionCustomization;
import com.netease.nim.uikit.session.SessionEventListener;
import com.netease.nim.uikit.session.activity.P2PMessageActivity;
import com.netease.nim.uikit.session.activity.TeamMessageActivity;
import com.netease.nim.uikit.session.emoji.StickerManager;
import com.netease.nim.uikit.session.module.MsgForwardFilter;
import com.netease.nim.uikit.session.module.MsgRevokeFilter;
import com.netease.nim.uikit.session.viewholder.MsgViewHolderBase;
import com.netease.nim.uikit.session.viewholder.MsgViewHolderFactory;
import com.netease.nim.uikit.team.activity.AdvancedTeamInfoActivity;
import com.netease.nim.uikit.team.activity.NormalTeamInfoActivity;
import com.netease.nim.uikit.uinfo.UserInfoHelper;
import com.netease.nimlib.sdk.AbortableFuture;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.auth.AuthService;
import com.netease.nimlib.sdk.auth.LoginInfo;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.team.constant.TeamTypeEnum;
import com.netease.nimlib.sdk.team.model.Team;
import com.netease.nimlib.sdk.uinfo.UserInfoProvider;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* UIKit能力输出类。
*/
public final class NimUIKit {
// context
private static Context context;
// 自己的用户帐号
private static String account;
// 用户信息提供者
private static UserInfoProvider userInfoProvider;
// 通讯录信息提供者
private static ContactProvider contactProvider;
// 地理位置信息提供者
private static LocationProvider locationProvider;
// 图片加载、缓存与管理组件
private static ImageLoaderKit imageLoaderKit;
// 会话窗口消息列表一些点击事件的响应处理函数
private static SessionEventListener sessionListener;
// 通讯录列表一些点击事件的响应处理函数
private static ContactEventListener contactEventListener;
// 转发消息过滤器
private static MsgForwardFilter msgForwardFilter;
// 撤回消息过滤器
private static MsgRevokeFilter msgRevokeFilter;
// 自定义推送配置
private static CustomPushContentProvider customPushContentProvider;
// 单聊界面定制
private static SessionCustomization commonP2PSessionCustomization;
// 群聊界面定制
private static SessionCustomization commonTeamSessionCustomization;
// 在线状态展示内容
private static OnlineStateContentProvider onlineStateContentProvider;
// 在线状态变化监听
private static List<OnlineStateChangeListener> onlineStateChangeListeners;
/**
* 初始化UIKit, 用户信息、联系人信息使用 {@link DefalutUserInfoProvider},{@link DefaultContactProvider}
* 若用户自行提供 userInfoProvider,contactProvider,请使用 {@link NimUIKit#init(Context, UserInfoProvider, ContactProvider)}
*
* @param context
*/
public static void init(Context context) {
init(context, null, null);
}
/**
* 初始化UIKit,须传入context以及用户信息提供者
*
* @param context 上下文
* @param userInfoProvider 用户信息提供者
* @param contactProvider 通讯录信息提供者
*/
public static void init(Context context, UserInfoProvider userInfoProvider, ContactProvider contactProvider) {
NimUIKit.context = context.getApplicationContext();
initUserInfoProvider(userInfoProvider);
initContactProvider(contactProvider);
initDefalutSessionCustomization();
initDefalutContactEventListener();
NimUIKit.imageLoaderKit = new ImageLoaderKit(context, null);
// init data cache
LoginSyncDataStatusObserver.getInstance().registerLoginSyncDataStatus(true); // 监听登录同步数据完成通知
DataCacheManager.observeSDKDataChanged(true);
if (!TextUtils.isEmpty(getAccount())) {
DataCacheManager.buildDataCache(); // build data cache on auto login
}
// init tools
StorageUtil.init(context, null);
ScreenUtil.init(context);
StickerManager.getInstance().init();
// init log
String path = StorageUtil.getDirectoryByDirType(StorageType.TYPE_LOG);
LogUtil.init(path, Log.DEBUG);
}
// 初始化用户信息提供者
private static void initUserInfoProvider(UserInfoProvider userInfoProvider) {
if (userInfoProvider == null) {
userInfoProvider = new DefalutUserInfoProvider(context);
}
NimUIKit.userInfoProvider = userInfoProvider;
}
// 初始化联系人信息提供者
private static void initContactProvider(ContactProvider contactProvider) {
if (contactProvider == null) {
contactProvider = new DefaultContactProvider();
}
NimUIKit.contactProvider = contactProvider;
}
// 初始化会话定制,群、P2P
private static void initDefalutSessionCustomization() {
if (commonP2PSessionCustomization == null) {
commonP2PSessionCustomization = new DefalutP2PSessionCustomization();
}
if (commonTeamSessionCustomization == null) {
commonTeamSessionCustomization = new DefalutTeamSessionCustomization();
}
}
// 初始化联系人点击事件
private static void initDefalutContactEventListener() {
if (contactEventListener == null) {
contactEventListener = new DefalutContactEventListener();
}
}
/**
* 打开单聊界面,若开发者未设置 {@link NimUIKit#setCommonP2PSessionCustomization(SessionCustomization)},
* 则定制化信息 SessionCustomization 为{@link DefalutP2PSessionCustomization}
* <p>
* 若需要为目标会话提供单独定义的SessionCustomization,请使用{@link NimUIKit#startChatting(Context, String, SessionTypeEnum, SessionCustomization, IMMessage)}
*
* @param context 上下文
* @param account 目标账号
*/
public static void startP2PSession(Context context, String account) {
startP2PSession(context, account, null);
}
/**
* 同 {@link NimUIKit#startP2PSession(Context, String)},同时聊天界面打开后,列表跳转至anchor位置
*
* @param context 上下文
* @param account 目标账号
* @param anchor 跳转到指定消息的位置,不需要跳转填null
*/
public static void startP2PSession(Context context, String account, IMMessage anchor) {
NimUIKit.startChatting(context, account, SessionTypeEnum.P2P, commonP2PSessionCustomization, anchor);
}
/**
* 打开群聊界面,若开发者未设置 {@link NimUIKit#setCommonTeamSessionCustomization(SessionCustomization)},
* 则定制化信息 SessionCustomization 为{@link DefalutTeamSessionCustomization}
* <p>
* 若需要为目标会话提供单独定义的SessionCustomization,请使用{@link NimUIKit#startChatting(Context, String, SessionTypeEnum, SessionCustomization, IMMessage)}
*
* @param context 上下文
* @param tid 群id
*/
public static void startTeamSession(Context context, String tid) {
startTeamSession(context, tid, null);
}
/**
* 同 {@link NimUIKit#startTeamSession(Context, String)},同时聊天界面打开后,列表跳转至anchor位置
*
* @param context 上下文
* @param tid 群id
* @param anchor 跳转到指定消息的位置,不需要跳转填null
*/
public static void startTeamSession(Context context, String tid, IMMessage anchor) {
NimUIKit.startChatting(context, tid, SessionTypeEnum.Team, commonTeamSessionCustomization, anchor);
}
/**
* 手动登陆,由于手动登陆完成之后,UIKit 需要设置账号、构建缓存等,使用此方法登陆 UIKit 会将这部分逻辑处理好,开发者只需要处理自己的逻辑即可
*
* @param loginInfo 登陆账号信息
* @param callback 登陆结果回调
*/
public static AbortableFuture<LoginInfo> doLogin(LoginInfo loginInfo, final RequestCallback<LoginInfo> callback) {
AbortableFuture<LoginInfo> loginRequest = NIMClient.getService(AuthService.class).login(loginInfo);
loginRequest.setCallback(new RequestCallback<LoginInfo>() {
@Override
public void onSuccess(LoginInfo loginInfo) {
NimUIKit.setAccount(loginInfo.getAccount());
DataCacheManager.buildDataCacheAsync();
callback.onSuccess(loginInfo);
}
@Override
public void onFailed(int code) {
callback.onFailed(code);
}
@Override
public void onException(Throwable exception) {
callback.onException(exception);
}
});
return loginRequest;
}
/**
* 释放缓存,一般在注销时调用
*/
public static void clearCache() {
DataCacheManager.clearDataCache();
}
/**
* 打开一个聊天窗口,开始聊天
*
* @param context 上下文
* @param id 聊天对象ID(用户帐号account或者群组ID)
* @param sessionType 会话类型
* @param customization 定制化信息。针对不同的聊天对象,可提供不同的定制化。
* @param anchor 跳转到指定消息的位置,不需要跳转填null
*/
public static void startChatting(Context context, String id, SessionTypeEnum sessionType, SessionCustomization
customization, IMMessage anchor) {
if (sessionType == SessionTypeEnum.P2P) {
P2PMessageActivity.start(context, id, customization, anchor);
} else if (sessionType == SessionTypeEnum.Team) {
TeamMessageActivity.start(context, id, customization, null, anchor);
}
}
/**
* 打开一个聊天窗口(用于从聊天信息中创建群聊时,打开群聊)
*
* @param context 上下文
* @param id 聊天对象ID(用户帐号account或者群组ID)
* @param sessionType 会话类型
* @param customization 定制化信息。针对不同的聊天对象,可提供不同的定制化。
* @param backToClass 返回的指定页面
* @param anchor 跳转到指定消息的位置,不需要跳转填null
*/
public static void startChatting(Context context, String id, SessionTypeEnum sessionType, SessionCustomization customization,
Class<? extends Activity> backToClass, IMMessage anchor) {
if (sessionType == SessionTypeEnum.Team) {
TeamMessageActivity.start(context, id, customization, backToClass, anchor);
}
}
/**
* 打开联系人选择器
*
* @param context 上下文(Activity)
* @param option 联系人选择器可选配置项
* @param requestCode startActivityForResult使用的请求码
*/
public static void startContactSelect(Context context, ContactSelectActivity.Option option, int requestCode) {
ContactSelectActivity.startActivityForResult(context, option, requestCode);
}
/**
* 打开讨论组或高级群资料页
*
* @param context 上下文
* @param teamId 群id
*/
public static void startTeamInfo(Context context, String teamId) {
Team team = TeamDataCache.getInstance().getTeamById(teamId);
if (team == null) {
return;
}
if (team.getType() == TeamTypeEnum.Advanced) {
AdvancedTeamInfoActivity.start(context, teamId); // 启动固定群资料页
} else if (team.getType() == TeamTypeEnum.Normal) {
NormalTeamInfoActivity.start(context, teamId); // 启动讨论组资料页
}
}
public static Context getContext() {
return context;
}
public static String getAccount() {
return account;
}
public static UserInfoProvider getUserInfoProvider() {
return userInfoProvider;
}
public static ContactProvider getContactProvider() {
return contactProvider;
}
public static LocationProvider getLocationProvider() {
return locationProvider;
}
public static ImageLoaderKit getImageLoaderKit() {
return imageLoaderKit;
}
/**
* 设置位置信息提供者
*
* @param locationProvider 位置信息提供者
*/
public static void setLocationProvider(LocationProvider locationProvider) {
NimUIKit.locationProvider = locationProvider;
}
/**
* 设置单聊界面定制 SessionCustomization
*
* @param commonP2PSessionCustomization 聊天界面定制化
*/
public static void setCommonP2PSessionCustomization(SessionCustomization commonP2PSessionCustomization) {
NimUIKit.commonP2PSessionCustomization = commonP2PSessionCustomization;
}
/**
* 设置群聊界面定制 SessionCustomization
*
* @param commonTeamSessionCustomization 聊天界面定制化
*/
public static void setCommonTeamSessionCustomization(SessionCustomization commonTeamSessionCustomization) {
NimUIKit.commonTeamSessionCustomization = commonTeamSessionCustomization;
}
/**
* 根据消息附件类型注册对应的消息项展示ViewHolder
*
* @param attach 附件类型
* @param viewHolder 消息ViewHolder
*/
public static void registerMsgItemViewHolder(Class<? extends MsgAttachment> attach, Class<? extends MsgViewHolderBase> viewHolder) {
MsgViewHolderFactory.register(attach, viewHolder);
}
/**
* 注册Tip类型消息项展示ViewHolder
*
* @param viewHolder Tip消息ViewHolder
*/
public static void registerTipMsgViewHolder(Class<? extends MsgViewHolderBase> viewHolder) {
MsgViewHolderFactory.registerTipMsgViewHolder(viewHolder);
}
/**
* 设置当前登录用户的帐号
*
* @param account 帐号
*/
public static void setAccount(String account) {
NimUIKit.account = account;
}
/**
* 获取聊天界面事件监听器
*
* @return
*/
public static SessionEventListener getSessionListener() {
return sessionListener;
}
/**
* 设置聊天界面的事件监听器
*
* @param sessionListener
*/
public static void setSessionListener(SessionEventListener sessionListener) {
NimUIKit.sessionListener = sessionListener;
}
/**
* 获取通讯录列表的事件监听器
*
* @return
*/
public static ContactEventListener getContactEventListener() {
return contactEventListener;
}
/**
* 设置通讯录列表的事件监听器
*
* @param contactEventListener
*/
public static void setContactEventListener(ContactEventListener contactEventListener) {
NimUIKit.contactEventListener = contactEventListener;
}
/**
* 当用户资料发生改动时,请调用此接口,通知更新UI
*
* @param accounts 有用户信息改动的帐号列表
*/
public static void notifyUserInfoChanged(List<String> accounts) {
UserInfoHelper.notifyChanged(accounts);
}
/**
* 设置转发消息过滤的监听器
*
* @param msgForwardFilter
*/
public static void setMsgForwardFilter(MsgForwardFilter msgForwardFilter) {
NimUIKit.msgForwardFilter = msgForwardFilter;
}
/**
* 获取转发消息过滤的监听器
*
* @return
*/
public static MsgForwardFilter getMsgForwardFilter() {
return msgForwardFilter;
}
/**
* 设置消息撤回的监听器
*
* @param msgRevokeFilter
*/
public static void setMsgRevokeFilter(MsgRevokeFilter msgRevokeFilter) {
NimUIKit.msgRevokeFilter = msgRevokeFilter;
}
/**
* 获取消息撤回的监听器
*
* @return
*/
public static MsgRevokeFilter getMsgRevokeFilter() {
return msgRevokeFilter;
}
/**
* @return
*/
public static CustomPushContentProvider getCustomPushContentProvider() {
return customPushContentProvider;
}
/**
* 注册自定义推送文案
*
* @return
*/
public static void CustomPushContentProvider(CustomPushContentProvider mixPushCustomConfig) {
NimUIKit.customPushContentProvider = mixPushCustomConfig;
}
public static OnlineStateContentProvider getOnlineStateContentProvider() {
return onlineStateContentProvider;
}
public static void setOnlineStateContentProvider(OnlineStateContentProvider onlineStateContentProvider) {
NimUIKit.onlineStateContentProvider = onlineStateContentProvider;
}
public static void addOnlineStateChangeListeners(OnlineStateChangeListener onlineStateChangeListener) {
if (onlineStateChangeListeners == null) {
onlineStateChangeListeners = new LinkedList<>();
}
onlineStateChangeListeners.add(onlineStateChangeListener);
}
public static void removeOnlineStateChangeListeners(OnlineStateChangeListener onlineStateChangeListener) {
if (onlineStateChangeListeners == null) {
return;
}
onlineStateChangeListeners.remove(onlineStateChangeListener);
}
public static void notifyOnlineStateChange(Set<String> accounts) {
if (onlineStateChangeListeners != null) {
for (OnlineStateChangeListener listener : onlineStateChangeListeners) {
listener.onlineStateChange(accounts);
}
}
}
/**
* 设置了 onlineStateContentProvider 则表示UIKit需要展示在线状态
*
* @return
*/
public static boolean enableOnlineState() {
return onlineStateContentProvider != null;
}
}