This commit is contained in:
2025-11-18 15:12:24 +08:00
parent c173c425ce
commit a7d2035e70
1361 changed files with 367452 additions and 0 deletions
@@ -0,0 +1,66 @@
package cn.shangyu.gdxzExpert.netease;
import android.content.Context;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nimlib.sdk.StatusBarNotificationConfig;
import cn.shangyu.gdxzExpert.utils.UIUtils;
/**
* Created by jezhee on 2/20/15.
*/
public class DemoCache {
private static Context context;
private static String account;
private static StatusBarNotificationConfig notificationConfig;
public static void clear() {
account = null;
}
public static String getAccount() {
return account;
}
private static boolean mainTaskLaunching;
public static void setAccount(String account) {
DemoCache.account = account;
NimUIKit.setAccount(account);
// AVChatKit.setAccount(account);
// RTSKit.setAccount(account);
}
public static void setNotificationConfig(StatusBarNotificationConfig notificationConfig) {
DemoCache.notificationConfig = notificationConfig;
}
public static StatusBarNotificationConfig getNotificationConfig() {
return notificationConfig;
}
public static Context getContext() {
return UIUtils.getContext();
}
public static void setContext(Context context) {
DemoCache.context = context.getApplicationContext();
// AVChatKit.setContext(context);
// RTSKit.setContext(context);
}
public static void setMainTaskLaunching(boolean mainTaskLaunching) {
DemoCache.mainTaskLaunching = mainTaskLaunching;
// AVChatKit.setMainTaskLaunching(mainTaskLaunching);
}
public static boolean isMainTaskLaunching() {
return mainTaskLaunching;
}
}
@@ -0,0 +1,284 @@
package cn.shangyu.gdxzExpert.netease;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import android.text.TextUtils;
import com.netease.nim.uikit.common.util.collection.CollectionUtil;
import com.netease.nimlib.push.net.lbs.IPVersion;
import com.netease.nimlib.push.packet.asymmetric.AsymmetricType;
import com.netease.nimlib.push.packet.symmetry.SymmetryType;
import com.netease.nimlib.sdk.NimHandshakeType;
import com.netease.nimlib.sdk.ServerAddresses;
import org.json.JSONException;
import org.json.JSONObject;
/**
* 网易云信私有化配置项
*/
public class DemoPrivatizationConfig {
/// BASIC
private static final String KEY_APP_KEY = "appkey";
private static final String KEY_MODULE = "module";
private static final String KEY_VERSION = "version";
private static final String KEY_HAND_SHAKE_TYPE = "hand_shake_type";
/// MAIN LINK
private static final String KEY_LBS = "lbs";
private static final String KEY_LINK = "link";
/// NOS UPLOAD
private static final String KEY_HTTPS_ENABLED = "https_enabled";
private static final String KEY_NOS_LBS = "nos_lbs";
private static final String KEY_NOS_UPLOADER = "nos_uploader";
private static final String KEY_NOS_UPLOADER_HOST = "nos_uploader_host";
/// NOS DOWNLOAD
private static final String KEY_NOS_DOWNLOADER = "nos_downloader";
private static final String KEY_NOS_ACCELERATE = "nos_accelerate";
private static final String KEY_NOS_ACCELERATE_HOST = "nos_accelerate_host";
private static final String KEY_NOS_ACCELERATE_HOST_LIST = "nos_accelerate_host_list";
private static final String KEY_NOS_CDN_ENABLE = "nos_cdn_enable";
/// SERVER
private static final String KEY_NT_SERVER = "nt_server";
// 握手协议(国密)
private static final String KEY_DEDICATED_CLUSTE_FLAG = "dedicated_cluste_flag";
private static final String KEY_NEGO_KEY_NECA = "nego_key_neca";
private static final String KEY_NEGO_KEY_ENCA_KEY_VERSION = "nego_key_enca_key_version";
private static final String KEY_NEGO_KEY_ENCA_KEY_PARTA = "nego_key_enca_key_parta";
private static final String KEY_NEGO_KEY_ENCA_KEY_PARTB = "nego_key_enca_key_partb";
private static final String KEY_COMM_ENCA = "comm_enca";
// IM IPv6
private static final String KEY_LINK_IPV6 = "link_ipv6";
private static final String KEY_IP_PROTOCOL_VERSION = "ip_protocol_version";
private static final String KEY_PROBE_IPV4_URL = "probe_ipv4_url";
private static final String KEY_PROBE_IPV6_URL = "probe_ipv6_url";
private static final String SHARE_NAME = "nim_demo_private_config";
private static final String KEY_CONFIG_ENABLE = "private_config_enable";
private static final String KEY_CONFIG_JSON = "private_config_json";
private static final String KEY_CHAT_ROOM_LIST_URL = "chatroomDemoListUrl";
private static final String BUCKET_NAME_PLACE_HOLDER = "{bucket}";
private static final String OBJECT_PLACE_HOLDER = "{object}";
private static final String CONFIG_URL = "config_private_url";
private static final String YSF_DEFALUT_URL_LABEL = "ysf_defalut_url_label";
private static final String YSF_DA_URL_LABEL = "ysf_da_url_label";
private static String appKey;
public static String getAppKey(Context context) {
if (isPrivateDisable(context)) {
return null;
}
if (appKey != null) {
return appKey;
}
JSONObject jsonObject = getConfig(context);
if (jsonObject == null) {
return null;
}
try {
appKey = jsonObject.getString(KEY_APP_KEY);
} catch (JSONException e) {
e.printStackTrace();
}
return appKey;
}
public static ServerAddresses getServerAddresses(Context context) {
if (isPrivateDisable(context)) {
return null;
}
return parseAddresses(getConfig(context));
}
public static void updateConfig(String config, Context context) {
if (TextUtils.isEmpty(config)) {
return;
}
getSP(context).edit().putString(KEY_CONFIG_JSON, config).apply();
}
public static String getChatListRoomUrl(Context context) {
return getConfig(context).optString(KEY_CHAT_ROOM_LIST_URL);
}
public static String getConfigUrl(Context context) {
return getSP(context).getString(CONFIG_URL, null);
}
public static void saveConfigUrl(Context context, String url) {
getSP(context).edit().putString(CONFIG_URL, url).apply();
}
public static void saveYsfDefaultUrl(Context context, String ysfDefaultUrl) {
getSP(context).edit().putString(YSF_DEFALUT_URL_LABEL, ysfDefaultUrl).apply();
}
public static void saveYsfDaUrl(Context context, String ysfDaUrl) {
getSP(context).edit().putString(YSF_DA_URL_LABEL, ysfDaUrl).apply();
}
public static String getYsfDefalutUrlLabel(Context context) {
return getSP(context).getString(YSF_DEFALUT_URL_LABEL, null);
}
public static String getYsfDaUrlLabel(Context context) {
return getSP(context).getString(YSF_DA_URL_LABEL, null);
}
public static void enablePrivateConfig(boolean enable, Context context) {
getSP(context).edit().putBoolean(KEY_CONFIG_ENABLE, enable).apply();
}
public static boolean isPrivateDisable(Context context) {
return !getSP(context).getBoolean(KEY_CONFIG_ENABLE, false);
}
public static JSONObject getConfig(Context context) {
String configStr = getSP(context).getString(KEY_CONFIG_JSON, null);
if (TextUtils.isEmpty(configStr)) {
return null;
}
return parse(configStr);
}
public static ServerAddresses checkConfigAndModifyConfig(String config) {
JSONObject jsonObject = parse(config);
return parseAddresses(jsonObject);
}
private static ServerAddresses parseAddresses(JSONObject jsonObject) {
if (jsonObject == null) {
return null;
}
ServerAddresses addresses = new ServerAddresses();
addresses.handshakeType = NimHandshakeType.value(jsonObject.optInt(KEY_HAND_SHAKE_TYPE, NimHandshakeType.V1.getValue()));
addresses.module = jsonObject.optString(KEY_MODULE);
addresses.publicKeyVersion = jsonObject.optInt(KEY_VERSION, 0);
addresses.lbs = jsonObject.optString(KEY_LBS);
addresses.defaultLink = jsonObject.optString(KEY_LINK);
addresses.nosUploadLbs = jsonObject.optString(KEY_NOS_LBS);
addresses.nosUploadDefaultLink = jsonObject.optString(KEY_NOS_UPLOADER);
addresses.nosUpload = jsonObject.optString(KEY_NOS_UPLOADER_HOST);
addresses.nosSupportHttps = jsonObject.optBoolean(KEY_HTTPS_ENABLED, false);
addresses.nosDownloadUrlFormat = jsonObject.optString(KEY_NOS_DOWNLOADER);
addresses.nosDownload = jsonObject.optString(KEY_NOS_ACCELERATE_HOST);
addresses.nosDownloadSet = CollectionUtil.createStringSetFromJSONArray(jsonObject.optJSONArray(KEY_NOS_ACCELERATE_HOST_LIST));
addresses.nosCdnEnable = jsonObject.optBoolean(KEY_NOS_CDN_ENABLE);
addresses.nosAccess = jsonObject.optString(KEY_NOS_ACCELERATE);
addresses.ntServerAddress = jsonObject.optString(KEY_NT_SERVER);
addresses.dedicatedClusteFlag = jsonObject.optInt(KEY_DEDICATED_CLUSTE_FLAG);
addresses.negoKeyNeca = AsymmetricType.value(jsonObject.optInt(KEY_NEGO_KEY_NECA, AsymmetricType.RSA.getValue()));
addresses.negoKeyEncaKeyVersion = jsonObject.optInt(KEY_NEGO_KEY_ENCA_KEY_VERSION);
addresses.negoKeyEncaKeyParta = jsonObject.optString(KEY_NEGO_KEY_ENCA_KEY_PARTA);
addresses.negoKeyEncaKeyPartb = jsonObject.optString(KEY_NEGO_KEY_ENCA_KEY_PARTB);
addresses.commEnca = SymmetryType.value(jsonObject.optInt(KEY_COMM_ENCA, SymmetryType.RC4.getValue()));
addresses.linkIpv6 = jsonObject.optString(KEY_LINK_IPV6);
addresses.ipProtocolVersion = IPVersion.value(jsonObject.optInt(KEY_IP_PROTOCOL_VERSION, IPVersion.IPV4.getValue()));
addresses.probeIpv4Url = jsonObject.optString(KEY_PROBE_IPV4_URL);
addresses.probeIpv6Url = jsonObject.optString(KEY_PROBE_IPV6_URL);
appKey = jsonObject.optString(KEY_APP_KEY);
autoAdjust(addresses);
checkValid(addresses);
return addresses;
}
private static void checkValid(ServerAddresses addresses) {
if (TextUtils.isEmpty(addresses.lbs)) {
throw new IllegalArgumentException("ServerAddresses lbs is null");
}
if (TextUtils.isEmpty(addresses.nosUploadLbs)) {
throw new IllegalArgumentException("ServerAddresses nosUploadLbs is null");
}
if (TextUtils.isEmpty(addresses.defaultLink)) {
throw new IllegalArgumentException("ServerAddresses defaultLink is null");
}
if (TextUtils.isEmpty(addresses.nosUploadDefaultLink)) {
throw new IllegalArgumentException("ServerAddresses nosUploadDefaultLink is null");
}
if (TextUtils.isEmpty(addresses.nosDownloadUrlFormat)) {
throw new IllegalArgumentException("ServerAddresses nosDownloadUrlFormat is null");
}
if (!checkFormatValid(addresses.nosDownloadUrlFormat)) {
throw new IllegalArgumentException("ServerAddresses nosDownloadUrlFormat is illegal");
}
if (addresses.nosSupportHttps && TextUtils.isEmpty(addresses.nosUpload)) {
throw new IllegalArgumentException("ServerAddresses nosSupportHttps is true , but nosUpload is null");
}
}
/**
* 自动调整字段,避免去改其他地方的逻辑
*/
private static void autoAdjust(@NonNull ServerAddresses addresses) {
addresses.module = TextUtils.isEmpty(addresses.module) ? null : addresses.module;
addresses.lbs = TextUtils.isEmpty(addresses.lbs) ? null : addresses.lbs;
addresses.defaultLink = TextUtils.isEmpty(addresses.defaultLink) ? null : addresses.defaultLink;
addresses.nosUploadLbs = TextUtils.isEmpty(addresses.nosUploadLbs) ? null : addresses.nosUploadLbs;
addresses.nosUploadDefaultLink = TextUtils.isEmpty(addresses.nosUploadDefaultLink) ? null : addresses.nosUploadDefaultLink;
addresses.nosUpload = TextUtils.isEmpty(addresses.nosUpload) ? null : addresses.nosUpload;
addresses.nosDownloadUrlFormat = TextUtils.isEmpty(addresses.nosDownloadUrlFormat) ? null : addresses.nosDownloadUrlFormat;
addresses.nosDownload = TextUtils.isEmpty(addresses.nosDownload) ? null : addresses.nosDownload;
addresses.nosAccess = TextUtils.isEmpty(addresses.nosAccess) ? null : addresses.nosAccess;
addresses.ntServerAddress = TextUtils.isEmpty(addresses.ntServerAddress) ? null : addresses.ntServerAddress;
addresses.negoKeyEncaKeyParta = TextUtils.isEmpty(addresses.negoKeyEncaKeyParta) ? null : addresses.negoKeyEncaKeyParta;
addresses.negoKeyEncaKeyPartb = TextUtils.isEmpty(addresses.negoKeyEncaKeyPartb) ? null : addresses.negoKeyEncaKeyPartb;
addresses.linkIpv6 = TextUtils.isEmpty(addresses.linkIpv6) ? null : addresses.linkIpv6;
addresses.probeIpv4Url = TextUtils.isEmpty(addresses.probeIpv4Url) ? null : addresses.probeIpv4Url;
addresses.probeIpv6Url = TextUtils.isEmpty(addresses.probeIpv6Url) ? null : addresses.probeIpv6Url;
appKey = TextUtils.isEmpty(appKey) ? null : appKey;
}
private static SharedPreferences getSP(Context context) {
return context.getSharedPreferences(SHARE_NAME, Context.MODE_PRIVATE);
}
private static JSONObject parse(String json) {
try {
return new JSONObject(json);
} catch (JSONException e) {
return null;
}
}
private static boolean checkFormatValid(String format) {
return !TextUtils.isEmpty(format) && format.contains(BUCKET_NAME_PLACE_HOLDER) && format.contains(
OBJECT_PLACE_HOLDER);
}
}
@@ -0,0 +1,126 @@
package cn.shangyu.gdxzExpert.netease;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import com.netease.nim.uikit.common.ToastHelper;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.NimStrings;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.model.BroadcastMessage;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.event.OnlineStateEventManager;
/**
* Created by hzchenkang on 2017/9/26.
* 用于初始化时,注册全局的广播、云信观察者等等云信相关业务
*/
public class NIMInitManager {
private static final String TAG = "NIMInitManager";
private NIMInitManager() {
}
private static class InstanceHolder {
static NIMInitManager receivers = new NIMInitManager();
}
public static NIMInitManager getInstance() {
return InstanceHolder.receivers;
}
public void init(boolean register) {
// 注册通知消息过滤器
registerIMMessageFilter();
// 注册语言变化监听广播
registerLocaleReceiver(register);
// 注册全局云信sdk 观察者
registerGlobalObservers(register);
// 初始化在线状态事件
OnlineStateEventManager.init();
}
private void registerGlobalObservers(boolean register) {
// 注册云信全员广播
registerBroadcastMessages(register);
}
private void registerLocaleReceiver(boolean register) {
if (register) {
updateLocale();
IntentFilter filter = new IntentFilter(Intent.ACTION_LOCALE_CHANGED);
DemoCache.getContext().registerReceiver(localeReceiver, filter);
} else {
DemoCache.getContext().unregisterReceiver(localeReceiver);
}
}
private BroadcastReceiver localeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
updateLocale();
}
}
};
private void updateLocale() {
Context context = DemoCache.getContext();
NimStrings strings = new NimStrings();
strings.status_bar_multi_messages_incoming = context.getString(com.netease.nim.uikit.R.string.nim_status_bar_multi_messages_incoming);
strings.status_bar_image_message = context.getString(com.netease.nim.uikit.R.string.nim_status_bar_image_message);
strings.status_bar_audio_message = context.getString(com.netease.nim.uikit.R.string.nim_status_bar_audio_message);
strings.status_bar_custom_message = context.getString(com.netease.nim.uikit.R.string.nim_status_bar_custom_message);
strings.status_bar_file_message = context.getString(com.netease.nim.uikit.R.string.nim_status_bar_file_message);
strings.status_bar_location_message = context.getString(com.netease.nim.uikit.R.string.nim_status_bar_location_message);
strings.status_bar_notification_message = context.getString(com.netease.nim.uikit.R.string.nim_status_bar_notification_message);
strings.status_bar_ticker_text = context.getString(com.netease.nim.uikit.R.string.nim_status_bar_ticker_text);
strings.status_bar_unsupported_message = context.getString(com.netease.nim.uikit.R.string.nim_status_bar_unsupported_message);
strings.status_bar_video_message = context.getString(com.netease.nim.uikit.R.string.nim_status_bar_video_message);
strings.status_bar_hidden_message_content = context.getString(com.netease.nim.uikit.R.string.nim_status_bar_hidden_msg_content);
NIMClient.updateStrings(strings);
}
/**
* 通知消息过滤器(如果过滤则该消息不存储不上报)
*/
private void registerIMMessageFilter() {
NIMClient.getService(MsgService.class).registerIMMessageFilter(message -> {
// if (UserPreferences.getMsgIgnore() && message.getAttachment() != null) {
//// if (message.getAttachment() instanceof UpdateTeamAttachment) {
//// UpdateTeamAttachment attachment = (UpdateTeamAttachment) message.getAttachment();
//// for (Map.Entry<TeamFieldEnum, Object> field : attachment.getUpdatedFields().entrySet()) {
//// if (field.getKey() == TeamFieldEnum.ICON) {
//// return true;
//// }
//// }
//// }
//// else if (message.getAttachment() instanceof AVChatAttachment) {
//// return false;// 是否过滤音视频消息
//// }
// }
return false;
});
}
/**
* 注册云信全服广播接收器
*
* @param register
*/
private void registerBroadcastMessages(boolean register) {
NIMClient.getService(MsgServiceObserve.class).observeBroadcastMessage(
(Observer<BroadcastMessage>) broadcastMessage -> ToastHelper.showToast(DemoCache.getContext(), "收到全员广播 :" + broadcastMessage.getContent()), register);
}
}
@@ -0,0 +1,223 @@
package cn.shangyu.gdxzExpert.netease;
import android.content.Context;
import android.graphics.Color;
import android.media.RingtoneManager;
import android.os.Environment;
import android.text.TextUtils;
import com.netease.nim.uikit.api.wrapper.MessageRevokeTip;
import com.netease.nim.uikit.business.session.viewholder.MsgViewHolderThumbBase;
import com.netease.nimlib.sdk.NosTokenSceneConfig;
import com.netease.nimlib.sdk.NotificationFoldStyle;
import com.netease.nimlib.sdk.SDKOptions;
import com.netease.nimlib.sdk.ServerAddresses;
import com.netease.nimlib.sdk.StatusBarNotificationConfig;
import com.netease.nimlib.sdk.mixpush.MixPushConfig;
import com.netease.nimlib.sdk.msg.MessageNotifierCustomization;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import java.io.IOException;
import cn.shangyu.gdxzExpert.netease.config.NimUserInfoProvider;
import cn.shangyu.gdxzExpert.netease.config.preference.UserPreferences;
//import com.netease.nim.demo.config.preference.UserPreferences;
//import com.netease.nim.demo.main.activity.WelcomeActivity;
/**
* Created by hzchenkang on 2017/9/26.
* <p>
* 云信sdk 自定义的SDK选项设置
*/
public class NimSDKOptionConfig {
public static SDKOptions getSDKOptions(Context context) {
SDKOptions options = new SDKOptions();
// 如果将新消息通知提醒托管给SDK完成,需要添加以下配置。
initStatusBarNotificationConfig(options);
// 配置 APP 保存图片/语音/文件/log等数据的目录
options.sdkStorageRootPath = getAppCacheDir(context) + "/nim"; // 可以不设置,那么将采用默认路径
// 配置是否需要预下载附件缩略图
options.preloadAttach = true;
// 配置附件缩略图的尺寸大小
options.thumbnailSize = MsgViewHolderThumbBase.getImageMaxEdge();
// 通知栏显示用户昵称和头像
options.userInfoProvider = new NimUserInfoProvider(DemoCache.getContext());
// 定制通知栏提醒文案(可选,如果不定制将采用SDK默认文案)
options.messageNotifierCustomization = messageNotifierCustomization;
// 在线多端同步未读数
options.sessionReadAck = true;
// 动图的缩略图直接下载原图
options.animatedImageThumbnailEnabled = true;
// 采用异步加载SDK
options.asyncInitSDK = true;
// 是否是弱IM场景
options.reducedIM = false;
// 是否检查manifest 配置,调试阶段打开,调试通过之后请关掉
options.checkManifestConfig = false;
// 是否启用群消息已读功能,默认关闭
options.enableTeamMsgAck = true;
// 打开消息撤回未读数-1的开关
options.shouldConsiderRevokedMessageUnreadCount = true;
// 云信私有化配置项
configServerAddress(options, context);
options.mixPushConfig = buildMixPushConfig();
// options.mNosTokenSceneConfig = createNosTokenScene();
options.loginCustomTag = "登录自定义字段";
options.useXLog = false;
// 会话置顶是否漫游
options.notifyStickTopSession = true;
return options;
}
public static final String TEST_NOS_SCENE_KEY = "test_nos_scene_key";
/**
* nos 场景配置
*/
private static NosTokenSceneConfig createNosTokenScene() {
NosTokenSceneConfig nosTokenSceneConfig = new NosTokenSceneConfig();
nosTokenSceneConfig.updateDefaultIMSceneExpireTime(1);
nosTokenSceneConfig.updateDefaultProfileSceneExpireTime(2);
// scene key 建议常量化,这样使用起来比较方便
nosTokenSceneConfig.appendCustomScene(TEST_NOS_SCENE_KEY, 4);
return nosTokenSceneConfig;
}
/**
* 配置 APP 保存图片/语音/文件/log等数据的目录
* 这里示例用SD卡的应用扩展存储目录
*/
public static String getAppCacheDir(Context context) {
String storageRootPath = null;
try {
// SD卡应用扩展存储区(APP卸载后,该目录下被清除,用户也可以在设置界面中手动清除),请根据APP对数据缓存的重要性及生命周期来决定是否采用此缓存目录.
// 该存储区在API 19以上不需要写权限,即可配置 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
if (context.getExternalCacheDir() != null) {
storageRootPath = context.getExternalCacheDir().getCanonicalPath();
}
} catch (IOException e) {
e.printStackTrace();
}
if (TextUtils.isEmpty(storageRootPath)) {
// SD卡应用公共存储区(APP卸载后,该目录不会被清除,下载安装APP后,缓存数据依然可以被加载。SDK默认使用此目录),该存储区域需要写权限!
storageRootPath = Environment.getExternalStorageDirectory() + "/" + DemoCache.getContext().getPackageName();
}
return storageRootPath;
}
private static void configServerAddress(final SDKOptions options, Context context) {
ServerAddresses serverConfig = DemoPrivatizationConfig.getServerAddresses(context);
if (serverConfig != null) {
options.serverConfig = serverConfig;
}
String appKey = DemoPrivatizationConfig.getAppKey(context);
if (!TextUtils.isEmpty(appKey)) {
options.appKey = appKey;
}
}
private static void initStatusBarNotificationConfig(SDKOptions options) {
// load 应用的状态栏配置
StatusBarNotificationConfig config = loadStatusBarNotificationConfig();
// load 用户的 StatusBarNotificationConfig 设置项
StatusBarNotificationConfig userConfig = UserPreferences.getStatusConfig();
// StatusBarNotificationConfig userConfig =null;
if (userConfig == null) {
userConfig = config;
} else {
// 新增的 UserPreferences 存储项更新,兼容 3.4 及以前版本
// 新增 notificationColor 存储,兼容3.6以前版本
// APP默认 StatusBarNotificationConfig 配置修改后,使其生效
userConfig.notificationEntrance = config.notificationEntrance;
userConfig.notificationFolded = config.notificationFolded;
userConfig.notificationFoldStyle = config.notificationFoldStyle;
userConfig.notificationColor = config.notificationColor;
}
// 持久化生效
UserPreferences.setStatusConfig(userConfig);
// SDK statusBarNotificationConfig 生效
options.statusBarNotificationConfig = userConfig;
}
// 这里开发者可以自定义该应用初始的 StatusBarNotificationConfig
private static StatusBarNotificationConfig loadStatusBarNotificationConfig() {
StatusBarNotificationConfig config = new StatusBarNotificationConfig();
// 点击通知需要跳转到的界面
// config.notificationEntrance = NewPatientActivity.class;
// config.notificationSmallIconId = R.drawable.ic_stat_notify_msg;
// config.notificationColor = DemoCache.getContext().getResources().getColor(R.color.color_blue_3a9efb);
// 通知铃声的uri字符串
// config.notificationSound = "android.resource://com.netease.nim.demo/raw/msg";
config.notificationSound= String.valueOf(RingtoneManager.getActualDefaultRingtoneUri(DemoCache.getContext(), RingtoneManager.TYPE_NOTIFICATION));
config.ring=true;
config.notificationFolded = true;
// config.notificationFolded = false;
config.notificationFoldStyle = NotificationFoldStyle.ALL;
config.downTimeEnableNotification = true;
// 呼吸灯配置
config.ledARGB = Color.GREEN;
config.ledOnMs = 1000;
config.ledOffMs = 1500;
// 是否APP ICON显示未读数红点(Android O有效)
config.showBadge = true;
// save cache,留做切换账号备用
DemoCache.setNotificationConfig(config);
return config;
}
private static MessageNotifierCustomization messageNotifierCustomization = new MessageNotifierCustomization() {
@Override
public String makeNotifyContent(String nick, IMMessage message) {
return null; // 采用SDK默认文案
}
@Override
public String makeTicker(String nick, IMMessage message) {
return null; // 采用SDK默认文案
}
@Override
public String makeRevokeMsgTip(String revokeAccount, IMMessage item) {
return MessageRevokeTip.getRevokeTipContent(item, revokeAccount);
}
};
private static MixPushConfig buildMixPushConfig() {
// 第三方推送配置
MixPushConfig config = new MixPushConfig();
// 小米推送
config.xmAppId = "2882303761517470793";
config.xmAppKey = "5431747048793";
config.xmCertificateName = "Expert_Mi_Push";
// 华为推送
config.hwAppId = "10526652";
config.hwCertificateName = "Expert_Hw_push_f";
// 魅族推送
config.mzAppId = "111710";
config.mzAppKey = "282bdd3a37ec4f898f47c5bbbf9d2369";
config.mzCertificateName = "DEMO_MZ_PUSH";
// fcm 推送,适用于海外用户,不使用fcm请不要配置
config.fcmCertificateName = "DEMO_FCM_PUSH";
// vivo推送
config.vivoCertificateName = "Expert_Vi_Push";
// oppo推送
config.oppoAppId = "3364888";
config.oppoAppKey = "75D5Vqsg63wok0S0w4SKog0w8";
config.oppoAppSercet = "416a4f5eF822ddcB73B627Cc310636D7";
config.oppoCertificateName = "Expert_Op_Push";
return config;
}
}
@@ -0,0 +1,181 @@
package cn.shangyu.gdxzExpert.netease.activity;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.wrapper.NimToolBarOptions;
import com.netease.nim.uikit.business.contact.selector.activity.ContactSelectActivity;
import com.netease.nim.uikit.business.team.helper.TeamHelper;
import com.netease.nim.uikit.common.ToastHelper;
import com.netease.nim.uikit.common.activity.ToolBarOptions;
import com.netease.nim.uikit.common.activity.UI;
import com.netease.nim.uikit.common.ui.imageview.HeadImageView;
import com.netease.nim.uikit.common.ui.widget.SwitchButton;
import com.netease.nim.uikit.common.util.sys.NetworkUtil;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.friend.FriendService;
import java.util.ArrayList;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.DemoCache;
import cn.shangyu.gdxzExpert.netease.contact.UserProfileActivity;
import cn.shangyu.gdxzExpert.netease.uinfo.UserInfoHelper;
/**
* Created by hzxuwen on 2015/10/13.
*/
public class MessageInfoActivity extends UI {
private final static String EXTRA_ACCOUNT = "EXTRA_ACCOUNT";
private static final int REQUEST_CODE_NORMAL = 1;
// data
private String account;
// view
private SwitchButton switchButton;
public static void startActivity(Context context, String account) {
Intent intent = new Intent();
intent.setClass(context, MessageInfoActivity.class);
intent.putExtra(EXTRA_ACCOUNT, account);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.message_info_activity);
ToolBarOptions options = new NimToolBarOptions();
options.titleId = com.netease.nim.uikit.R.string.message_info;
options.navigateId = com.netease.nim.uikit.R.drawable.actionbar_dark_back_icon;
setToolBar(R.id.toolbar, options);
account = getIntent().getStringExtra(EXTRA_ACCOUNT);
findViews();
}
@Override
protected void onResume() {
super.onResume();
updateSwitchBtn();
}
private void findViews() {
HeadImageView userHead = (HeadImageView) findViewById(R.id.user_layout).findViewById(com.netease.nim.uikit.R.id.imageViewHeader);
TextView userName = (TextView) findViewById(R.id.user_layout).findViewById(com.netease.nim.uikit.R.id.textViewName);
userHead.loadBuddyAvatar(account);
userName.setText(UserInfoHelper.getUserDisplayName(account));
userHead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openUserProfile();
}
});
((TextView) findViewById(R.id.create_team_layout).findViewById(com.netease.nim.uikit.R.id.textViewName)).setText(com.netease.nim.uikit.R.string.create_normal_team);
HeadImageView addImage = (HeadImageView) findViewById(R.id.create_team_layout).findViewById(com.netease.nim.uikit.R.id.imageViewHeader);
addImage.setBackgroundResource(com.netease.nim.uikit.R.drawable.nim_team_member_add_selector);
addImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createTeamMsg();
}
});
((TextView) findViewById(R.id.toggle_layout).findViewById(com.netease.nim.uikit.R.id.user_profile_title)).setText(com.netease.nim.uikit.R.string.msg_notice);
switchButton = (SwitchButton) findViewById(R.id.toggle_layout).findViewById(com.netease.nim.uikit.R.id.user_profile_toggle);
switchButton.setOnChangedListener(onChangedListener);
}
private void updateSwitchBtn() {
boolean notice = NIMClient.getService(FriendService.class).isNeedMessageNotify(account);
switchButton.setCheck(notice);
}
private SwitchButton.OnChangedListener onChangedListener = new SwitchButton.OnChangedListener() {
@Override
public void OnChanged(View v, final boolean checkState) {
if (!NetworkUtil.isNetAvailable(MessageInfoActivity.this)) {
ToastHelper.showToast(MessageInfoActivity.this, com.netease.nim.uikit.R.string.network_is_not_available);
switchButton.setCheck(!checkState);
return;
}
NIMClient.getService(FriendService.class).setMessageNotify(account, checkState).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
if (checkState) {
ToastHelper.showToast(MessageInfoActivity.this, "开启消息提醒成功");
} else {
ToastHelper.showToast(MessageInfoActivity.this, "关闭消息提醒成功");
}
}
@Override
public void onFailed(int code) {
if (code == 408) {
ToastHelper.showToast(MessageInfoActivity.this, com.netease.nim.uikit.R.string.network_is_not_available);
} else {
ToastHelper.showToast(MessageInfoActivity.this, "on failed:" + code);
}
switchButton.setCheck(!checkState);
}
@Override
public void onException(Throwable exception) {
}
});
}
};
private void openUserProfile() {
UserProfileActivity.start(this, account);
}
/**
* 创建群聊
*/
private void createTeamMsg() {
ArrayList<String> memberAccounts = new ArrayList<>();
memberAccounts.add(account);
ContactSelectActivity.Option option = TeamHelper.getCreateContactSelectOption(memberAccounts, 50);
NimUIKit.startContactSelector(this, option, REQUEST_CODE_NORMAL);// 创建群
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == REQUEST_CODE_NORMAL) {
final ArrayList<String> selected = data.getStringArrayListExtra(ContactSelectActivity.RESULT_DATA);
// if (selected != null && !selected.isEmpty()) {
// TeamCreateHelper.createNormalTeam(MessageInfoActivity.this, selected, true, new RequestCallback<CreateTeamResult>() {
// @Override
// public void onSuccess(CreateTeamResult param) {
// finish();
// }
//
// @Override
// public void onFailed(int code) {
//
// }
//
// @Override
// public void onException(Throwable exception) {
//
// }
// });
// } else {
ToastHelper.showToast(DemoCache.getContext(), "请选择至少一个联系人!");
}
}
}
}
@@ -0,0 +1,58 @@
package cn.shangyu.gdxzExpert.netease.bagder;
import android.os.Handler;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.common.framework.infra.Handlers;
import cn.shangyu.gdxzExpert.utils.SharePrefUtil;
import cn.shangyu.gdxzExpert.utils.UIUtils;
import me.leolin.shortcutbadger.ShortcutBadger;
/**
* APP图标未读数红点更新接口
* https://github.com/leolin310148/ShortcutBadger
* <p>
* Created by huangjun on 2017/7/25.
*/
public class Badger {
private static final String TAG = "Badger";
private static Handler handler;
private static boolean support = true;
public static volatile int unreadFollow= SharePrefUtil.getInt(UIUtils.getContext(),"unreadFollow",0);
public static void saveUnreadFollow()
{
SharePrefUtil.saveInt(UIUtils.getContext(),"unreadFollow",unreadFollow);
}
public static void updateBadgerCount(final int unreadCount) {
if (!support) {
return; // O版本及以上不再支持
}
if (handler == null) {
handler = Handlers.sharedInstance().newHandler("Badger");
}
handler.removeCallbacksAndMessages(null);
handler.postDelayed(new Runnable() {
@Override
public void run() {
int badgerCount = unreadCount+unreadFollow;
if (badgerCount < 0) {
badgerCount = 0;
} else if (badgerCount > 99) {
badgerCount = 99;
}
boolean res = ShortcutBadger.applyCount(NimUIKit.getContext(), badgerCount);
if (!res) {
support = false; // 如果失败就不要再使用了!
}
// Log.i(TAG, "update badger count " + (res ? "success" : "failed"));
}
}, 200);
}
}
@@ -0,0 +1,70 @@
package cn.shangyu.gdxzExpert.netease.big;
import android.text.TextUtils;
import com.netease.nim.uikit.business.session.constant.Extras;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseQuickAdapter;
import com.netease.nim.uikit.impl.NimUIKitImpl;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
public class BigCommonRecentViewHolder extends BigRecentViewHolder {
BigCommonRecentViewHolder(BaseQuickAdapter adapter) {
super(adapter);
}
@Override
protected String getContent(RecentContact recent) {
return descOfMsg(recent);
}
@Override
protected String getOnlineStateContent(RecentContact recent) {
if (recent.getSessionType() == SessionTypeEnum.P2P && NimUIKitImpl.enableOnlineState()) {
return NimUIKitImpl.getOnlineStateContentProvider().getSimpleDisplay(recent.getContactId());
} else {
return super.getOnlineStateContent(recent);
}
}
String descOfMsg(RecentContact recent) {
if(recent.getExtension()!=null&&recent.getExtension().get(Extras.CAO_GAO)!=null
&& !TextUtils.isEmpty(recent.getExtension().get(Extras.CAO_GAO).toString()) && !"".equalsIgnoreCase(recent.getExtension().get(Extras.CAO_GAO).toString())
&& !"null".equalsIgnoreCase(recent.getExtension().get(Extras.CAO_GAO).toString()))
{
return Extras.CAO_GAO_TI_HUAN+recent.getExtension().get(Extras.CAO_GAO);
}
else if (recent.getMsgType() == MsgTypeEnum.text) {
return recent.getContent();
} else if (recent.getMsgType() == MsgTypeEnum.tip) {
String digest = null;
if (getCallback() != null) {
digest = getCallback().getDigestOfTipMsg(recent);
}
if (digest == null) {
digest = NimUIKitImpl.getRecentCustomization().getDefaultDigest(recent);
}
return digest;
} else if (recent.getAttachment() != null) {
String digest = null;
if (getCallback() != null) {
digest = getCallback().getDigestOfAttachment(recent, recent.getAttachment());
}
if (digest == null) {
digest = NimUIKitImpl.getRecentCustomization().getDefaultDigest(recent);
}
return digest;
} else if (recent.getSessionType() == SessionTypeEnum.Ysf) {
return recent.getContent();
}
return "[未知]";
}
}
@@ -0,0 +1,314 @@
package cn.shangyu.gdxzExpert.netease.big;
import android.graphics.drawable.AnimationDrawable;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.business.recent.RecentContactsCallback;
import com.netease.nim.uikit.business.session.emoji.MoonUtil;
import com.netease.nim.uikit.common.framework.infra.Handlers;
import com.netease.nim.uikit.common.ui.drop.DropFake;
import com.netease.nim.uikit.common.ui.drop.DropManager;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseQuickAdapter;
import com.netease.nim.uikit.common.ui.recyclerview.holder.BaseViewHolder;
import com.netease.nim.uikit.common.ui.recyclerview.holder.RecyclerViewHolder;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.netease.nim.uikit.common.util.sys.TimeUtil;
import com.netease.nim.uikit.impl.cache.StickTopCache;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.msg.constant.MsgStatusEnum;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.nos.NosService;
import com.netease.nimlib.sdk.nos.model.NosThumbParam;
import com.netease.nimlib.sdk.nos.util.NosThumbImageUtil;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.ptop.RecentContactAdapter;
import cn.shangyu.gdxzExpert.netease.uinfo.UserInfoHelper;
import cn.shangyu.gdxzExpert.utils.StringUtil;
import static cn.shangyu.gdxzExpert.utils.UIUtils.getContext;
public abstract class BigRecentViewHolder extends RecyclerViewHolder<BaseQuickAdapter, BaseViewHolder, RecentContact> {
public BigRecentViewHolder(BaseQuickAdapter adapter) {
super(adapter);
}
private int lastUnreadCount = 0;
protected RelativeLayout portraitPanel;
protected ImageView imgHead;
protected TextView tvNickname;
protected TextView tvMessage;
protected TextView tvDatetime;
// 消息发送错误状态标记,目前没有逻辑处理
protected ImageView imgMsgStatus;
protected View bottomLine;
protected View topLine;
// 未读红点(一个占坑,一个全屏动画)
protected DropFake tvUnread;
private ImageView imgUnreadExplosion;
protected TextView tvOnlineState;
private static Integer labelWidth;
// 子类覆写
protected abstract String getContent(RecentContact recent);
@Override
public void convert(BaseViewHolder holder, RecentContact data, int position, boolean isScrolling) {
inflate(holder, data);
refresh(holder, data, position);
}
public void inflate(BaseViewHolder holder, final RecentContact recent) {
this.portraitPanel = holder.getView(R.id.portrait_panel);
this.imgHead = holder.getView(R.id.img_head);
this.tvNickname = holder.getView(R.id.tv_nickname);
this.tvMessage = holder.getView(R.id.tv_message);
this.tvUnread = holder.getView(R.id.unread_number_tip);
this.imgUnreadExplosion = holder.getView(R.id.unread_number_explosion);
this.tvDatetime = holder.getView(R.id.tv_date_time);
this.imgMsgStatus = holder.getView(R.id.img_msg_status);
this.bottomLine = holder.getView(R.id.bottom_line);
this.topLine = holder.getView(R.id.top_line);
this.tvOnlineState = holder.getView(R.id.tv_online_state);
holder.addOnClickListener(R.id.unread_number_tip);
this.tvUnread.setTouchListener(new DropFake.ITouchListener() {
@Override
public void onDown() {
DropManager.getInstance().setCurrentId(recent);
DropManager.getInstance().down(tvUnread, tvUnread.getText());
}
@Override
public void onMove(float curX, float curY) {
DropManager.getInstance().move(curX, curY);
}
@Override
public void onUp() {
DropManager.getInstance().up();
}
});
}
public void refresh(BaseViewHolder holder, RecentContact recent, final int position) {
// unread count animation
boolean shouldBoom = lastUnreadCount > 0 && recent.getUnreadCount() == 0; // 未读数从N->0执行爆裂动画;
lastUnreadCount = recent.getUnreadCount();
updateBackground(holder, recent, position);
loadPortrait(recent);
updateNickLabel(
UserInfoHelper.getUserTitleName(recent.getContactId(), recent.getSessionType())
);
updateOnlineState(recent);
updateMsgLabel(holder, recent);
updateNewIndicator(recent);
if (shouldBoom) {
Object o = DropManager.getInstance().getCurrentId();
if (o instanceof String && o.equals("0")) {
imgUnreadExplosion.setImageResource(com.netease.nim.uikit.R.drawable.nim_explosion);
imgUnreadExplosion.setVisibility(View.VISIBLE);
Handlers.sharedHandler(holder.getContext()).post(() -> {
((AnimationDrawable) imgUnreadExplosion.getDrawable()).start();
// 解决部分手机动画无法播放的问题(例如华为荣耀)
getAdapter().notifyItemChanged(getAdapter().getViewHolderPosition(position));
});
}
} else {
imgUnreadExplosion.setVisibility(View.GONE);
}
}
private void updateBackground(BaseViewHolder holder, RecentContact recent, int position) {
topLine.setVisibility(getAdapter().isFirstDataItem(position) ? View.GONE : View.VISIBLE);
bottomLine.setVisibility(getAdapter().isLastDataItem(position) ? View.VISIBLE : View.GONE);
holder.getConvertView().setBackgroundResource(recent == null || StickTopCache.isStickTop(recent) ?
com.netease.nim.uikit.R.drawable.nim_recent_contact_sticky_selecter : com.netease.nim.uikit.R.drawable.nim_touch_bg);
}
protected void loadPortrait(RecentContact recent) {
// 设置头像
if (recent.getSessionType() == SessionTypeEnum.P2P) {
// imgHead.loadBuddyAvatar(recent.getContactId());
if(!StringUtil.isEmpty(UserInfoHelper.getUserDisplayPhoto(recent.getContactId())))
{
loadAvatar("",UserInfoHelper.getUserDisplayPhoto(recent.getContactId()));
}
else
{
loadBuddyAvatar(recent.getContactId());
}
} else if (recent.getSessionType() == SessionTypeEnum.Team) {
// Team team = NimUIKit.getTeamProvider().getTeamById(recent.getContactId());
// loadTeamIconByTeam(team);
} else if (recent.getSessionType() == SessionTypeEnum.SUPER_TEAM) {
// SuperTeam team = NimUIKit.getSuperTeamProvider().getTeamById(recent.getContactId());
// loadSuperTeamIconByTeam(team);
} else if (recent.getSessionType() == SessionTypeEnum.Ysf) {
imgHead.setImageResource(com.netease.nim.uikit.R.drawable.nim_ic_ysf_default_icon);
}
}
/**
* 加载用户头像(默认大小的缩略图)
*
* @param url 头像地址
*/
public void loadAvatar(String roomId, final String url) {
changeUrlBeforeLoad(roomId, url, R.drawable.icon_touxiang_persion_gray_big, 54);
}
/**
* 如果图片是上传到云信服务器,并且用户开启了文件安全功能,那么这里可能是短链,需要先换成源链才能下载。
* 如果没有使用云信存储或没开启文件安全,那么不用这样做
*/
private void changeUrlBeforeLoad(String roomId, final String url, final int defaultResId,
final int thumbSize) {
if (TextUtils.isEmpty(url)) {
// avoid useless call
loadImage(url, defaultResId, thumbSize);
} else {
/*
* 若使用网易云信云存储,这里可以设置下载图片的压缩尺寸,生成下载URL
* 如果图片来源是非网易云信云存储,请不要使用NosThumbImageUtil
*/
NIMClient.getService(NosService.class).getOriginUrlFromShortUrl(url).setCallback(
new RequestCallbackWrapper<String>() {
@Override
public void onResult(int code, String result, Throwable exception) {
if (TextUtils.isEmpty(result)) {
result = url;
}
final String thumbUrl = makeAvatarThumbNosUrl(result, thumbSize);
loadImage(thumbUrl, defaultResId, thumbSize);
}
});
}
}
/**
* 生成头像缩略图NOS URL地址(用作ImageLoader缓存的key)
*/
private static String makeAvatarThumbNosUrl(final String url, final int thumbSize) {
if (TextUtils.isEmpty(url)) {
return url;
}
return thumbSize > 0 ? NosThumbImageUtil.makeImageThumbUrl(url,
NosThumbParam.ThumbType.Crop,
thumbSize, thumbSize) : url;
}
/**
* ImageLoader异步加载
*/
private void loadImage(final String url, final int defaultResId, final int thumbSize) {
RequestOptions requestOptions = new RequestOptions().centerCrop().placeholder(defaultResId)
.error(defaultResId).override(thumbSize,
thumbSize);
Glide.with(getContext().getApplicationContext()).asBitmap().load(url).apply(requestOptions)
.into(imgHead);
}
/**
* 加载用户头像(默认大小的缩略图)
*
* @param account 用户账号
*/
public void loadBuddyAvatar(String account) {
loadAvatar("", NimUIKit.getContactProvider().getAlias(account));
}
private void updateNewIndicator(RecentContact recent) {
int unreadNum = recent.getUnreadCount();
tvUnread.setVisibility(unreadNum > 0 ? View.VISIBLE : View.GONE);
tvUnread.setText(unreadCountShowRule(unreadNum));
}
private void updateMsgLabel(BaseViewHolder holder, RecentContact recent) {
// 显示消息具体内容
MoonUtil.identifyRecentVHFaceExpressionAndTags(holder.getContext(), tvMessage, getContent(recent), -1, 0.45f);
//tvMessage.setText(getContent());
MsgStatusEnum status = recent.getMsgStatus();
if (status == null) {
imgMsgStatus.setVisibility(View.GONE);
} else {
switch (status) {
case fail:
imgMsgStatus.setImageResource(com.netease.nim.uikit.R.drawable.nim_g_ic_failed_small);
imgMsgStatus.setVisibility(View.VISIBLE);
break;
case sending:
imgMsgStatus.setImageResource(com.netease.nim.uikit.R.drawable.nim_recent_contact_ic_sending);
imgMsgStatus.setVisibility(View.VISIBLE);
break;
default:
imgMsgStatus.setVisibility(View.GONE);
break;
}
}
String timeString = TimeUtil.getTimeShowString(recent.getTime(), true);
tvDatetime.setText(timeString);
}
protected String getOnlineStateContent(RecentContact recent) {
return "";
}
protected void updateOnlineState(RecentContact recent) {
if (recent.getSessionType() == SessionTypeEnum.Team || recent.getSessionType() == SessionTypeEnum.SUPER_TEAM) {
tvOnlineState.setVisibility(View.GONE);
} else {
String onlineStateContent = getOnlineStateContent(recent);
if (TextUtils.isEmpty(onlineStateContent)) {
tvOnlineState.setVisibility(View.GONE);
} else {
tvOnlineState.setVisibility(View.VISIBLE);
tvOnlineState.setText(getOnlineStateContent(recent));
}
}
}
protected void updateNickLabel(String nick) {
if (labelWidth == null) {
labelWidth = ScreenUtil.screenWidth - ScreenUtil.dip2px(120); // 减去固定的头像和时间宽度;
}
if (labelWidth > 0) {
tvNickname.setMaxWidth(labelWidth);
}
tvNickname.setText(nick);
}
protected String unreadCountShowRule(int unread) {
unread = Math.min(unread, 99);
return String.valueOf(unread);
}
protected RecentContactsCallback getCallback() {
return ((RecentContactAdapter) getAdapter()).getCallback();
}
}
@@ -0,0 +1,283 @@
package cn.shangyu.gdxzExpert.netease.chatroom;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.business.chatroom.fragment.ChatRoomMessageFragment;
import com.netease.nim.uikit.common.ToastHelper;
import com.netease.nim.uikit.common.activity.UI;
import com.netease.nim.uikit.common.ui.dialog.DialogMaker;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.AbortableFuture;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.StatusCode;
import com.netease.nimlib.sdk.chatroom.ChatRoomService;
import com.netease.nimlib.sdk.chatroom.ChatRoomServiceObserver;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomInfo;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomKickOutEvent;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomStatusChangeData;
import com.netease.nimlib.sdk.chatroom.model.EnterChatRoomData;
import com.netease.nimlib.sdk.chatroom.model.EnterChatRoomResultData;
import java.util.Collections;
import java.util.Random;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.constants.EnterMode;
import cn.shangyu.gdxzExpert.netease.constants.Extras;
import cn.shangyu.gdxzExpert.netease.thridparty.ChatRoomHttpClient;
/**
* 聊天室
* Created by hzxuwen on 2015/12/14.
*/
public class ChatRoomActivity extends UI {
private static final String TAG = ChatRoomActivity.class.getSimpleName();
/**
* 聊天室基本信息
*/
private String roomId;
private String appKey, account, pwd, link;
private int mode = EnterMode.NORMAL;
private ChatRoomInfo roomInfo;
private boolean hasEnterSuccess = false; // 是否已经成功登录聊天室
private ChatRoomFragment fragment;
/**
* 子页面
*/
private ChatRoomMessageFragment messageFragment;
private AbortableFuture<EnterChatRoomResultData> enterRequest;
public static void start(Context context, String roomId, int mode, String appKey,
String account, String pwd, String link) {
Intent intent = new Intent();
intent.setClass(context, ChatRoomActivity.class);
intent.putExtra(Extras.ROOM_ID, roomId);
intent.putExtra(Extras.MODE, mode);
intent.putExtra(Extras.APP_KEY, appKey);
intent.putExtra(Extras.ACCOUNT, account);
intent.putExtra(Extras.PWD, pwd);
intent.putExtra(Extras.LINK, link);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_room_activity);
boolean ok = getIntentData();
if (!ok) {
finish();
return;
}
// 注册监听
registerObservers(true);
// 登录聊天室
enterRoom();
}
private boolean getIntentData() {
roomId = getIntent().getStringExtra(Extras.ROOM_ID);
mode = getIntent().getIntExtra(Extras.MODE, EnterMode.NORMAL);
appKey = getIntent().getStringExtra(Extras.APP_KEY);
account = getIntent().getStringExtra(Extras.ACCOUNT);
pwd = getIntent().getStringExtra(Extras.PWD);
if (mode == EnterMode.INDEPENDENT) {
if (TextUtils.isEmpty(appKey)) {
ToastHelper.showToast(ChatRoomActivity.this,
getString(R.string.independent_mode_error));
return false;
}
}
link = getIntent().getStringExtra(Extras.LINK);
return true;
}
@Override
protected void onDestroy() {
super.onDestroy();
registerObservers(false);
}
@Override
public void onBackPressed() {
if (messageFragment == null || !messageFragment.onBackPressed()) {
super.onBackPressed();
}
logoutChatRoom();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (messageFragment != null) {
messageFragment.onActivityResult(requestCode, resultCode, data);
}
}
private void enterRoom() {
DialogMaker.showProgressDialog(this, null, "", true, dialog -> {
if (enterRequest != null) {
enterRequest.abort();
onLoginDone();
finish();
}
}).setCanceledOnTouchOutside(false);
hasEnterSuccess = false;
EnterChatRoomData data = new EnterChatRoomData(roomId);
if (mode == EnterMode.INDEPENDENT) {
data.setAppKey(appKey);
data.setIndependentMode((roomId, account) -> {
if (TextUtils.isEmpty(link)) {
ChatRoomHttpClient client = ChatRoomHttpClient.getInstance();
return client.fetchChatRoomAddress(roomId, appKey, account);
}
return Collections.singletonList(link);
}, account, pwd);
if (TextUtils.isEmpty(account)) {
data.setNick(String.format("soduku%s", new Random().nextInt(100)));
data.setAvatar(
"https://nim.nosdn.127.net/MTAxMTAxMA==/bmltYV8yNDM0MzQ4OV8xNTMyMDUzNzM3ODkzXzJlNGQ3ZjA5LWI2MjgtNDNiNy1hZTIwLTBhYTgzMjZhYzBjZQ==?thumbnail=540x540&imageView&tostatic=0");
}
}
enterRequest = NIMClient.getService(ChatRoomService.class).enterChatRoomEx(data, 1);
enterRequest.setCallback(new RequestCallback<EnterChatRoomResultData>() {
@Override
public void onSuccess(EnterChatRoomResultData result) {
onLoginDone();
roomInfo = result.getRoomInfo();
NimUIKit.enterChatRoomSuccess(result, false);
initChatRoomFragment();
initMessageFragment();
hasEnterSuccess = true;
}
@Override
public void onFailed(int code) {
onLoginDone();
if (code == ResponseCode.RES_CHATROOM_BLACKLIST) {
ToastHelper.showToast(ChatRoomActivity.this, "你已被拉入黑名单,不能再进入");
} else if (code == ResponseCode.RES_ENONEXIST) {
ToastHelper.showToast(ChatRoomActivity.this, "聊天室不存在");
} else {
ToastHelper.showToast(ChatRoomActivity.this,
"enter chat room failed, code=" + code);
}
finish();
}
@Override
public void onException(Throwable exception) {
onLoginDone();
ToastHelper.showToast(ChatRoomActivity.this,
"enter chat room exception, e=" + exception.getMessage());
finish();
}
});
}
private void registerObservers(boolean register) {
NIMClient.getService(ChatRoomServiceObserver.class).observeOnlineStatus(onlineStatus,
register);
NIMClient.getService(ChatRoomServiceObserver.class).observeKickOutEvent(kickOutObserver,
register);
}
private void logoutChatRoom() {
NIMClient.getService(ChatRoomService.class).exitChatRoom(roomId);
onExitedChatRoom();
}
public void onExitedChatRoom() {
NimUIKit.exitedChatRoom(roomId);
finish();
}
Observer<ChatRoomStatusChangeData> onlineStatus = new Observer<ChatRoomStatusChangeData>() {
@Override
public void onEvent(ChatRoomStatusChangeData chatRoomStatusChangeData) {
if (!chatRoomStatusChangeData.roomId.equals(roomId)) {
return;
}
if (chatRoomStatusChangeData.status == StatusCode.CONNECTING) {
DialogMaker.updateLoadingMessage("连接中...");
} else if (chatRoomStatusChangeData.status == StatusCode.LOGINING) {
DialogMaker.updateLoadingMessage("登录中...");
} else if (chatRoomStatusChangeData.status == StatusCode.LOGINED) {
if (fragment != null) {
fragment.updateOnlineStatus(true);
}
} else if (chatRoomStatusChangeData.status == StatusCode.UNLOGIN) {
if (fragment != null) {
fragment.updateOnlineStatus(false);
}
// 登录成功后,断网重连交给云信SDK,如果重连失败,可以查询具体失败的原因
if (hasEnterSuccess) {
int code = NIMClient.getService(ChatRoomService.class).getEnterErrorCode(roomId);
ToastHelper.showToast(ChatRoomActivity.this, "getEnterErrorCode=" + code);
LogUtil.d(TAG, "chat room enter error code:" + code);
}
} else if (chatRoomStatusChangeData.status == StatusCode.NET_BROKEN) {
if (fragment != null) {
fragment.updateOnlineStatus(false);
}
ToastHelper.showToast(ChatRoomActivity.this, R.string.net_broken);
}
LogUtil.i(TAG, "chat room online status changed to " +
chatRoomStatusChangeData.status.name());
}
};
Observer<ChatRoomKickOutEvent> kickOutObserver = (Observer<ChatRoomKickOutEvent>) chatRoomKickOutEvent -> {
ToastHelper.showToast(ChatRoomActivity.this,
"被踢出聊天室,原因:" + chatRoomKickOutEvent.getReason());
onExitedChatRoom();
};
private void initChatRoomFragment() {
fragment = (ChatRoomFragment) getSupportFragmentManager().findFragmentById(R.id.chat_rooms_fragment);
if (fragment != null) {
fragment.updateView();
} else {
// 如果Fragment还未Create完成,延迟初始化
getHandler().postDelayed(this::initChatRoomFragment, 50);
}
}
private void initMessageFragment() {
messageFragment = (ChatRoomMessageFragment) getSupportFragmentManager().findFragmentById(
R.id.chat_room_message_fragment);
if (messageFragment != null) {
messageFragment.init(roomId);
} else {
// 如果Fragment还未Create完成,延迟初始化
getHandler().postDelayed(this::initMessageFragment, 50);
}
}
private void onLoginDone() {
enterRequest = null;
DialogMaker.dismissProgressDialog();
}
public ChatRoomInfo getRoomInfo() {
return roomInfo;
}
}
@@ -0,0 +1,169 @@
package cn.shangyu.gdxzExpert.netease.chatroom;
import android.os.Bundle;
import androidx.viewpager.widget.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.chatroom.ChatRoomService;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.ui.PagerSlidingTabStrip;
/**
* 聊天室顶层fragment
* Created by hzxuwen on 2015/12/14.
*/
public class ChatRoomFragment extends ChatRoomTabFragment implements
ViewPager.OnPageChangeListener {
private PagerSlidingTabStrip tabs;
private ViewPager viewPager;
private ChatRoomTabPagerAdapter adapter;
private int scrollState;
private ImageView imageView;
private TextView statusText;
private static final boolean SHOW_BARRAGE = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
protected void onInit() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.chat_room_fragment, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
findViews();
setupPager();
setupTabs();
}
public void updateOnlineStatus(boolean isOnline) {
statusText.setVisibility(isOnline ? View.GONE : View.VISIBLE);
}
public void updateView() {
// ChatRoomHelper.setCoverImage(((ChatRoomActivity) getActivity()).getRoomInfo().getRoomId(),
// imageView, true);
}
@Override
public void onDestroy() {
super.onDestroy();
}
private void findViews() {
imageView = findView(R.id.chat_room_view);
statusText = findView(R.id.online_status);
final ImageView backImage = findView(R.id.back_arrow);
tabs = findView(R.id.chat_room_tabs);
viewPager = findView(R.id.chat_room_viewpager);
backImage.setOnClickListener(v -> {
NIMClient.getService(ChatRoomService.class).exitChatRoom(
((ChatRoomActivity) getActivity()).getRoomInfo().getRoomId());
((ChatRoomActivity) getActivity()).onExitedChatRoom();
});
// 是否演示弹幕控件
// if (SHOW_BARRAGE) {
// ViewStub barrageViewStub = findView(R.id.barrage_view_stub);
// barrageViewStub.inflate();
// View barrageViewRoot = findView(R.id.barrage_view_after_inflate);
// final BarrageSurfaceView barrageView = barrageViewRoot.findViewById(R.id.barrage_view);
// final String barrageText1 = "欢迎进入直播间";
// final String barrageText2 = "Welcome to live room";
// Handlers.sharedHandler(getActivity()).postDelayed(() -> {
// BarrageConfig config = new BarrageConfig();
// config.setDuration(4500);
// // 初始化弹幕控件
// barrageView.init(config);
// for (int i = 1; i <= 200; i++) {
// barrageView.addTextBarrage((i % 2 == 0 ? barrageText1 : barrageText2) + i);
// }
// }, 1000);
// }
}
private void setupPager() {
// CACHE COUNT
adapter = new ChatRoomTabPagerAdapter(getFragmentManager(), getActivity(), viewPager);
viewPager.setOffscreenPageLimit(adapter.getCacheCount());
// page swtich animation
// viewPager.setPageTransformer(true, new FadeInOutPageTransformer());
// ADAPTER
viewPager.setAdapter(adapter);
// TAKE OVER CHANGE
viewPager.addOnPageChangeListener(this);
}
private void setupTabs() {
tabs.setOnCustomTabListener(new PagerSlidingTabStrip.OnCustomTabListener() {
@Override
public int getTabLayoutResId(int position) {
return R.layout.chat_room_tab_layout;
}
@Override
public boolean screenAdaptation() {
return true;
}
});
tabs.setViewPager(viewPager);
tabs.setOnTabClickListener(adapter);
tabs.setOnTabDoubleTapListener(adapter);
}
/********************
* OnPageChangeListener
**************************/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TO TABS
tabs.onPageScrolled(position, positionOffset, positionOffsetPixels);
// TO ADAPTER
adapter.onPageScrolled(position);
}
@Override
public void onPageSelected(int position) {
// TO TABS
tabs.onPageSelected(position);
selectPage(position);
}
@Override
public void onPageScrollStateChanged(int state) {
// TO TABS
tabs.onPageScrollStateChanged(state);
scrollState = state;
selectPage(viewPager.getCurrentItem());
}
private void selectPage(int page) {
// TO PAGE
if (scrollState == ViewPager.SCROLL_STATE_IDLE) {
adapter.onPageSelected(viewPager.getCurrentItem());
}
}
}
@@ -0,0 +1,42 @@
package cn.shangyu.gdxzExpert.netease.chatroom;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.model.chatroom.ChatRoomSessionCustomization;
import com.netease.nim.uikit.business.session.actions.BaseAction;
import java.util.ArrayList;
import cn.shangyu.gdxzExpert.netease.session.action.EasyAction;
import cn.shangyu.gdxzExpert.netease.session.action.ShoppingAction;
import cn.shangyu.gdxzExpert.netease.session.action.TeachAction;
import cn.shangyu.gdxzExpert.netease.session.action.VisitAction;
/**
* UIKit自定义聊天室消息界面用法展示类
* <p>
* Created by huangjun on 2017/9/18.
*/
public class ChatRoomSessionHelper {
public static void init() {
registerViewHolders();
NimUIKit.setCommonChatRoomSessionCustomization(getChatRoomSessionCustomization());
}
private static void registerViewHolders() {
// NimUIKit.registerChatRoomMsgItemViewHolder(GuessAttachment.class, ChatRoomMsgViewHolderGuess.class);
}
private static ChatRoomSessionCustomization getChatRoomSessionCustomization() {
ArrayList<BaseAction> actions = new ArrayList<>();
// actions.add(new GuessAction());
actions.add(new EasyAction());
actions.add(new TeachAction());
actions.add(new VisitAction());
actions.add(new ShoppingAction());
ChatRoomSessionCustomization customization = new ChatRoomSessionCustomization();
customization.actions = actions;
return customization;
}
}
@@ -0,0 +1,42 @@
package cn.shangyu.gdxzExpert.netease.chatroom;
import cn.shangyu.gdxzExpert.R;
/**
* Created by hzxuwen on 2015/12/14.
*/
public enum ChatRoomTab {
CHAT_ROOM_MESSAGE(0, MessageTabFragment.class, com.netease.nim.uikit.R.string.chat_room_message, R.layout.chat_room_message_tab),
MASTER(1, MasterTabFragment.class, com.netease.nim.uikit.R.string.chat_room_master, R.layout.chat_room_master_tab),
// ONLINE_PEOPLE(2, OnlinePeopleTabFragment.class, R.string.chat_room_online_people, R.layout.chat_room_people_tab);
ONLINE_PEOPLE(2, MasterTabFragment.class, com.netease.nim.uikit.R.string.chat_room_master, R.layout.chat_room_master_tab);
public final int tabIndex;
public final Class<? extends ChatRoomTabFragment> clazz;
public final int resId;
public final int fragmentId;
public final int layoutId;
ChatRoomTab(int index, Class<? extends ChatRoomTabFragment> clazz, int resId, int layoutId) {
this.tabIndex = index;
this.clazz = clazz;
this.resId = resId;
this.fragmentId = index;
this.layoutId = layoutId;
}
public static final ChatRoomTab fromTabIndex(int tabIndex) {
for (ChatRoomTab value : ChatRoomTab.values()) {
if (value.tabIndex == tabIndex) {
return value;
}
}
return null;
}
}
@@ -0,0 +1,58 @@
package cn.shangyu.gdxzExpert.netease.chatroom;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.netease.nim.uikit.common.fragment.TabFragment;
import cn.shangyu.gdxzExpert.R;
/**
* Created by hzxuwen on 2015/12/14.
*/
public abstract class ChatRoomTabFragment extends TabFragment {
private boolean loaded = false;
private ChatRoomTab tabData;
protected abstract void onInit();
protected boolean inited() {
return loaded;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.main_tab_fragment_container, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
public void attachTabData(ChatRoomTab tabData) {
this.tabData = tabData;
}
@Override
public void onCurrent() {
super.onCurrent();
if (!loaded && loadRealLayout()) {
loaded = true;
onInit();
}
}
private boolean loadRealLayout() {
ViewGroup root = (ViewGroup) getView();
if (root != null) {
root.removeAllViewsInLayout();
View.inflate(root.getContext(), tabData.layoutId, root);
}
return root != null;
}
}
@@ -0,0 +1,69 @@
package cn.shangyu.gdxzExpert.netease.chatroom;
import android.content.Context;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager.widget.ViewPager;
import java.util.List;
import cn.shangyu.gdxzExpert.netease.ui.SlidingTabPagerAdapter;
/**
* 聊天室主TAB适配器
* Created by hzxuwen on 2015/12/14.
*/
public class ChatRoomTabPagerAdapter extends SlidingTabPagerAdapter {
public ChatRoomTabPagerAdapter(FragmentManager fm, Context context, ViewPager pager) {
super(fm, ChatRoomTab.values().length, context.getApplicationContext(), pager);
for (ChatRoomTab tab : ChatRoomTab.values()) {
try {
ChatRoomTabFragment fragment = null;
List<Fragment> fs = fm.getFragments();
if (fs != null) {
for (Fragment f : fs) {
if (f.getClass() == tab.clazz) {
fragment = (ChatRoomTabFragment) f;
break;
}
}
}
if (fragment == null) {
fragment = tab.clazz.newInstance();
}
fragment.setState(this);
fragment.attachTabData(tab);
fragments[tab.tabIndex] = fragment;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
@Override
public int getCacheCount() {
return ChatRoomTab.values().length;
}
@Override
public int getCount() {
return ChatRoomTab.values().length;
}
@Override
public CharSequence getPageTitle(int position) {
ChatRoomTab tab = ChatRoomTab.fromTabIndex(position);
int resId = tab != null ? tab.resId : 0;
return resId != 0 ? context.getText(resId) : "";
}
}
@@ -0,0 +1,141 @@
package cn.shangyu.gdxzExpert.netease.chatroom;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.common.fragment.TFragment;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.chatroom.ChatRoomService;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomInfo;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.widget.ChatRoomImageView;
/**
* 聊天室主播fragment
* Created by hzxuwen on 2015/12/17.
*/
public class MasterFragment extends TFragment {
private static final String TAG = MasterFragment.class.getSimpleName();
private ChatRoomImageView imageView;
private TextView nameText;
private TextView countText;
private TextView announceText;
private LinearLayout announceLayout;
private LinearLayout noAnnounceLayout;
private ChatRoomMember master;
private long lastClickTime = 0;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.master_fragment, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
findViews();
}
public void onCurrent() {
if (!isFastClick()) {
fetchRoomInfo();
}
}
/**
* 频率控制,至少间隔一分钟
*
* @return
*/
private boolean isFastClick() {
long current = System.currentTimeMillis();
long time = current - lastClickTime;
if (0 < time && time < 60000) {
return true;
}
lastClickTime = current;
return false;
}
private void findViews() {
imageView = findView(R.id.master_head_image);
imageView.loadAvatarByUrl("", ""); // 网络不好的时候,设置一个默认头像
nameText = findView(R.id.master_name);
countText = findView(R.id.online_total);
announceText = findView(R.id.announce_content);
announceLayout = findView(R.id.announce_layout);
noAnnounceLayout = findView(R.id.no_announce_layout);
}
private void fetchRoomInfo() {
String roomId = ((ChatRoomActivity) getActivity()).getRoomInfo().getRoomId();
NIMClient.getService(ChatRoomService.class).fetchRoomInfo(roomId).setCallback(
new RequestCallback<ChatRoomInfo>() {
@Override
public void onSuccess(ChatRoomInfo param) {
getChatRoomMaster(param);
}
@Override
public void onFailed(int code) {
LogUtil.d(TAG, "fetch room info failed:" + code);
}
@Override
public void onException(Throwable exception) {
LogUtil.d(TAG, "fetch room info exception:" + exception);
}
});
}
private void getChatRoomMaster(final ChatRoomInfo roomInfo) {
master = NimUIKit.getChatRoomProvider().getChatRoomMember(roomInfo.getRoomId(),
roomInfo.getCreator());
if (master != null) {
updateView(roomInfo);
} else {
NimUIKit.getChatRoomProvider().fetchMember(roomInfo.getRoomId(), roomInfo.getCreator(),
(success, result, code) -> {
if (success) {
master = result;
updateView(roomInfo);
}
});
}
}
private void updateView(ChatRoomInfo chatRoomInfo) {
imageView.loadAvatarByUrl(master.getRoomId(), master.getAvatar());
nameText.setText(TextUtils.isEmpty(master.getNick()) ? "" : master.getNick());
countText.setText(String.valueOf(chatRoomInfo.getOnlineUserCount()));
if (TextUtils.isEmpty(chatRoomInfo.getAnnouncement())) {
noAnnounceLayout.setVisibility(View.VISIBLE);
announceLayout.setVisibility(View.GONE);
} else {
announceLayout.setVisibility(View.VISIBLE);
noAnnounceLayout.setVisibility(View.GONE);
announceText.setText(chatRoomInfo.getAnnouncement());
}
}
}
@@ -0,0 +1,27 @@
package cn.shangyu.gdxzExpert.netease.chatroom;
import cn.shangyu.gdxzExpert.R;
/**
* 主播基类fragment
* Created by hzxuwen on 2015/12/14.
*/
public class MasterTabFragment extends ChatRoomTabFragment {
private MasterFragment fragment;
@Override
protected void onInit() {
fragment = (MasterFragment) getActivity().getSupportFragmentManager().findFragmentById(
R.id.master_fragment);
}
@Override
public void onCurrent() {
super.onCurrent();
if (fragment != null) {
fragment.onCurrent();
}
}
}
@@ -0,0 +1,59 @@
package cn.shangyu.gdxzExpert.netease.chatroom;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.netease.nim.uikit.business.chatroom.fragment.ChatRoomMessageFragment;
import cn.shangyu.gdxzExpert.R;
/**
* 直播互动基类fragment
* Created by hzxuwen on 2015/12/14.
*/
public class MessageTabFragment extends ChatRoomTabFragment {
private ChatRoomMessageFragment fragment;
public MessageTabFragment() {
this.setContainerId(ChatRoomTab.CHAT_ROOM_MESSAGE.fragmentId);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
onCurrent();
}
@Override
protected void onInit() {
findViews();
}
@Override
public void onCurrent() {
super.onCurrent();
}
@Override
public void onLeave() {
super.onLeave();
if (fragment != null) {
fragment.onLeave();
}
}
private void findViews() {
fragment = (ChatRoomMessageFragment) getActivity().getSupportFragmentManager()
.findFragmentById(
R.id.chat_room_message_fragment);
}
}
@@ -0,0 +1,44 @@
package cn.shangyu.gdxzExpert.netease.config;
import com.netease.nim.uikit.api.model.contact.ContactProvider;
import com.netease.nim.uikit.impl.cache.FriendDataCache;
import java.util.List;
import cn.shangyu.gdxzExpert.netease.uinfo.UserInfoHelper;
/**
* UIKit默认的通讯录(联系人)数据源提供者,
* Created by hzchenkang on 2016/12/19.
*/
public class DefaultContactProvider implements ContactProvider {
@Override
public List<String> getUserInfoOfMyFriends() {
return FriendDataCache.getInstance().getMyFriendAccounts();
}
@Override
public int getMyFriendsCount() {
return FriendDataCache.getInstance().getMyFriendCounts();
}
@Override
public String getAlias(String account) {
return UserInfoHelper.getUserDisplayPhoto(account);
// Friend friend = FriendDataCache.getInstance().getFriendByAccount(account);
// if (friend != null && !TextUtils.isEmpty(friend.getAlias())) {
// return friend.getAlias();
// }
// return null;
}
@Override
public boolean isMyFriend(String account) {
return FriendDataCache.getInstance().isMyFriend(account);
}
}
@@ -0,0 +1,18 @@
package cn.shangyu.gdxzExpert.netease.config;
public class DemoServers {
//
// 好友列表信息服务器地址
//
private static final String API_SERVER_TEST = "http://apptest.netease.im/api/"; // 测试
private static final String API_SERVER = "https://app.netease.im/api/"; // 线上
public static String apiServer() {
return ServerConfig.testServer() ? API_SERVER_TEST : API_SERVER;
}
public static String chatRoomAPIServer() {
return apiServer() + "chatroom/";
}
}
@@ -0,0 +1,11 @@
package cn.shangyu.gdxzExpert.netease.config;
/**
* Created by jezhee on 4/19/15.
*/
public class ExtraOptions {
public static void provide() {
/// EMPTY NOW
}
}
@@ -0,0 +1,72 @@
package cn.shangyu.gdxzExpert.netease.config;
import static cn.shangyu.gdxzExpert.utils.CommonUtil.IS_BIG_MUDULE;
import static cn.shangyu.gdxzExpert.utils.CommonUtil.showGuideView;
import android.content.Intent;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.auth.AuthService;
import java.io.Serializable;
import java.util.List;
import cn.shangyu.gdxzExpert.ecdemo.ui.SDKCoreHelper;
import cn.shangyu.gdxzExpert.netease.DemoCache;
import cn.shangyu.gdxzExpert.report.ReportService;
import cn.shangyu.gdxzExpert.report.reportBean;
import cn.shangyu.gdxzExpert.utils.CommonUtil;
import cn.shangyu.gdxzExpert.utils.Constant;
import cn.shangyu.gdxzExpert.utils.DataCleanManager;
import cn.shangyu.gdxzExpert.utils.SharePrefUtil;
import cn.shangyu.gdxzExpert.utils.UIUtils;
/**
* 注销帮助类
* Created by huangjun on 2015/10/8.
*/
public class LogoutHelper {
public static String addUMTokenuuid = SharePrefUtil.getString(UIUtils.getContext(), Constant.uuid, "");
public static void logout() {
Boolean isbig=CommonUtil.BigModule();
Boolean guideView=SharePrefUtil.getBoolean(UIUtils.getContext(),showGuideView,true);
addUMTokenuuid = SharePrefUtil.getString(UIUtils.getContext(), Constant.uuid, "");
SharePrefUtil.saveString(UIUtils.getContext(), Constant.yx_accid, "");
SharePrefUtil.saveString(UIUtils.getContext(), Constant.yx_token, "");
SharePrefUtil.saveString(UIUtils.getContext(), "isbound_wechat", "");
SharePrefUtil.clear(UIUtils.getContext(), "isLogin");
startReport(null);
// Constant.Repotr_token="";
// SharePrefUtil.clear(UIUtils.getContext(), SharePrefUtil.getString(UIUtils.getContext(), Constant.SP_IS_FIRST_NAME,
// Constant.mobile, "") + "my_provinceId");
// SharePrefUtil.clear(UIUtils.getContext(), SharePrefUtil.getString(UIUtils.getContext(), Constant.SP_IS_FIRST_NAME,
// Constant.mobile, "") + "my_cityId");
// SharePrefUtil.clear(UIUtils.getContext(), SharePrefUtil.getString(UIUtils.getContext(), Constant.SP_IS_FIRST_NAME,
// Constant.mobile, "") + "my_disctictId");
// SharePrefUtil.clear(UIUtils.getContext(), Constant.SP_IS_FIRST_NAME);
DataCleanManager.cleanApplicationData(UIUtils.getContext());
SDKCoreHelper.logout(true);
// 清理缓存&注销监听&清除状态
NimUIKit.logout();
DemoCache.clear();
NIMClient.getService(AuthService.class).logout();
SharePrefUtil.saveBoolean(UIUtils.getContext(),IS_BIG_MUDULE,isbig);
SharePrefUtil.saveBoolean(UIUtils.getContext(),showGuideView,guideView);
}
public static void startReport(List<reportBean> list)
{
Intent intent = new Intent(UIUtils.getContext(), ReportService.class);
if(list!=null)
{
intent.putExtra("report_list", (Serializable) list);
}
intent.putExtra("report_token", Constant.Repotr_token);
UIUtils.getContext().startService(intent);
}
}
@@ -0,0 +1,119 @@
package cn.shangyu.gdxzExpert.netease.config;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import com.netease.nim.uikit.R;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.business.team.helper.TeamHelper;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.nos.NosService;
import com.netease.nimlib.sdk.superteam.SuperTeam;
import com.netease.nimlib.sdk.team.model.Team;
import com.netease.nimlib.sdk.uinfo.UserInfoProvider;
import com.netease.nimlib.sdk.uinfo.model.UserInfo;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import cn.shangyu.gdxzExpert.netease.uinfo.UserInfoHelper;
/**
* 初始化sdk 需要的用户信息提供者,现主要用于内置通知提醒获取昵称和头像
* <p>
* 注意不要与 IUserInfoProvider 混淆,后者是 UIKit 与 demo 之间的数据共享接口
* <p>
*/
public class NimUserInfoProvider implements UserInfoProvider {
private Context context;
public NimUserInfoProvider(Context context) {
this.context = context;
}
@Override
public UserInfo getUserInfo(String account) {
return NimUIKit.getUserInfoProvider().getUserInfo(account);
}
@Override
public Bitmap getAvatarForMessageNotifier(SessionTypeEnum sessionType, String sessionId) {
/*
* 注意:这里最好从缓存里拿,如果加载时间过长会导致通知栏延迟弹出!该函数在后台线程执行!
*/
Bitmap bm = null;
int defResId = R.drawable.icon_touxiang_persion_gray_big;
CountDownLatch countDownLatch = new CountDownLatch(1);
final String[] originUrl = new String[1];
if (SessionTypeEnum.P2P == sessionType) {
UserInfo user = getUserInfo(sessionId);
originUrl[0]=UserInfoHelper.getUserDisplayPhoto(sessionId);
// originUrl[0] = user != null ? user.getAvatar() : null;
} else if (SessionTypeEnum.Team == sessionType) {
Team team = NimUIKit.getTeamProvider().getTeamById(sessionId);
originUrl[0] = team != null ? team.getIcon() : null;
} else if (SessionTypeEnum.SUPER_TEAM == sessionType) {
SuperTeam team = NimUIKit.getSuperTeamProvider().getTeamById(sessionId);
originUrl[0] = team != null ? team.getIcon() : null;
}
NIMClient.getService(NosService.class).getOriginUrlFromShortUrl(originUrl[0]).setCallback(
new RequestCallbackWrapper<String>() {
@Override
public void onResult(int code, String result, Throwable exception) {
originUrl[0] = result;
countDownLatch.countDown();
}
});
try {
countDownLatch.await(200, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!TextUtils.isEmpty(originUrl[0])) {
bm = NimUIKit.getImageLoaderKit().getNotificationBitmapFromCache(originUrl[0]);
}
if (bm == null) {
if (SessionTypeEnum.Team == sessionType || SessionTypeEnum.SUPER_TEAM == sessionType) {
defResId = R.drawable.nim_avatar_group;
}
Drawable drawable = context.getResources().getDrawable(defResId);
if (drawable instanceof BitmapDrawable) {
bm = ((BitmapDrawable) drawable).getBitmap();
}
}
return bm;
}
@Override
public String getDisplayTitleForMessageNotifier(IMMessage message) {
return null;
}
@Override
public String getDisplayNameForMessageNotifier(String account, String sessionId,
SessionTypeEnum sessionType) {
String nick = null;
if (sessionType == SessionTypeEnum.P2P) {
// nick = NimUIKit.getContactProvider().getAlias(account);
nick= UserInfoHelper.getUserDisplayName(account);
} else if (sessionType == SessionTypeEnum.Team) {
nick = NimUIKit.getContactProvider().getAlias(account);
if (TextUtils.isEmpty(nick)) {
nick = TeamHelper.getTeamNick(sessionId, account);
}
}
if (TextUtils.isEmpty(nick)) {
return null; // 返回null,交给sdk处理。如果对方有设置nick,sdk会显示nick
}
return nick;
}
}
@@ -0,0 +1,19 @@
package cn.shangyu.gdxzExpert.netease.config;
public final class ServerConfig {
public enum ServerEnv {
TEST("t"),
PRE_REL("p"),
REL("r"),;
String tag;
ServerEnv(String tag) {
this.tag = tag;
}
}
public static boolean testServer() {
return ServerEnvs.SERVER == ServerEnv.TEST;
}
}
@@ -0,0 +1,12 @@
package cn.shangyu.gdxzExpert.netease.config;
final class ServerEnvs {
//
// ENVs
// DEFAULT Env.REL
//
static final ServerConfig.ServerEnv SERVER = ServerConfig.ServerEnv.REL;
}
@@ -0,0 +1,99 @@
package cn.shangyu.gdxzExpert.netease.config.preference;
import android.content.Context;
import android.content.SharedPreferences;
import com.netease.nimlib.push.net.lbs.IPVersion;
import com.netease.nimlib.push.packet.asymmetric.AsymmetricType;
import com.netease.nimlib.push.packet.symmetry.SymmetryType;
import com.netease.nimlib.sdk.NimHandshakeType;
import cn.shangyu.gdxzExpert.netease.DemoCache;
/**
* Created by hzxuwen on 2015/4/13.
*/
public class Preferences {
private static final String KEY_USER_ACCOUNT = "account";
private static final String KEY_USER_TOKEN = "token";
private static final String KEY_HANDSHAKE = "handshake";
private static final String KEY_ASYMMETRIC = "asymmetric";
private static final String KEY_SYMMETRY = "symmetry";
private static final String KEY_IPV = "ipv";
public static void saveUserAccount(String account) {
saveString(KEY_USER_ACCOUNT, account);
}
public static String getUserAccount() {
return getString(KEY_USER_ACCOUNT);
}
public static void saveUserToken(String token) {
saveString(KEY_USER_TOKEN, token);
}
public static String getUserToken() {
return getString(KEY_USER_TOKEN);
}
public static void saveHandshakeType(NimHandshakeType handshakeType) {
saveInt(KEY_HANDSHAKE, handshakeType.getValue());
}
public static NimHandshakeType getHandshakeType() {
return NimHandshakeType.value(getInt(KEY_HANDSHAKE, NimHandshakeType.V1.getValue()));
}
public static void saveAsymmetric(AsymmetricType asymmetric) {
saveInt(KEY_ASYMMETRIC, asymmetric.getValue());
}
public static AsymmetricType getAsymmetric() {
return AsymmetricType.value(getInt(KEY_ASYMMETRIC));
}
public static void saveSymmetry(SymmetryType symmetry) {
saveInt(KEY_SYMMETRY, symmetry.getValue());
}
public static SymmetryType getSymmetry() {
return SymmetryType.value(getInt(KEY_SYMMETRY));
}
public static void saveIpv(IPVersion ipv) {
saveInt(KEY_IPV, ipv.getValue());
}
public static IPVersion getIpv() {
return IPVersion.value(getInt(KEY_IPV));
}
private static void saveInt(String key, int value) {
SharedPreferences.Editor editor = getSharedPreferences().edit();
editor.putInt(key, value);
editor.commit();
}
private static int getInt(String key) {
return getSharedPreferences().getInt(key, 0);
}
private static int getInt(String key, int defaultValue) {
return getSharedPreferences().getInt(key, defaultValue);
}
private static void saveString(String key, String value) {
SharedPreferences.Editor editor = getSharedPreferences().edit();
editor.putString(key, value);
editor.commit();
}
private static String getString(String key) {
return getSharedPreferences().getString(key, null);
}
static SharedPreferences getSharedPreferences() {
return DemoCache.getContext().getSharedPreferences("Demo", Context.MODE_PRIVATE);
}
}
@@ -0,0 +1,283 @@
package cn.shangyu.gdxzExpert.netease.config.preference;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import com.alibaba.fastjson.JSONObject;
import com.netease.nimlib.sdk.NotificationFoldStyle;
import com.netease.nimlib.sdk.StatusBarNotificationConfig;
import cn.shangyu.gdxzExpert.netease.DemoCache;
/**
* Created by hzxuwen on 2015/4/13.
*/
public class UserPreferences {
private final static String KEY_DOWNTIME_TOGGLE = "down_time_toggle";
private final static String KEY_SB_NOTIFY_TOGGLE = "sb_notify_toggle";
private final static String KEY_OFFLINE_PUSH = "offline_push";
private final static String KEY_TEAM_ANNOUNCE_CLOSED = "team_announce_closed";
private final static String KEY_STATUS_BAR_NOTIFICATION_CONFIG = "KEY_STATUS_BAR_NOTIFICATION_CONFIG";
// 测试过滤通知
private final static String KEY_MSG_IGNORE = "KEY_MSG_IGNORE";
// 响铃配置
private final static String KEY_RING_TOGGLE = "KEY_RING_TOGGLE";
// 震动配置
private final static String KEY_VIBRATE_TOGGLE = "KEY_VIBRATE_TOGGLE";
// 呼吸灯配置
private final static String KEY_LED_TOGGLE = "KEY_LED_TOGGLE";
// 通知栏标题配置
private final static String KEY_NOTICE_CONTENT_TOGGLE = "KEY_NOTICE_CONTENT_TOGGLE";
// 删除好友同时删除备注
private final static String KEY_DELETE_FRIEND_AND_DELETE_ALIAS = "KEY_DELETE_FRIEND_AND_DELETE_ALIAS";
// 保存在线状态订阅时间
private final static String KEY_SUBSCRIBE_TIME = "KEY_SUBSCRIBE_TIME";
/*************************no disturb begin***************************************/
public static final String DOWN_TIME_BEGIN = "downTimeBegin";
public static final String DOWN_TIME_END = "downTimeEnd";
public static final String DOWN_TIME_TOGGLE = "downTimeToggle";
public static final String DOWN_TIME_ENABLE_NOTIFICATION = "downTimeEnableNotification";
public static final String RING = "ring";
public static final String VIBRATE = "vibrate";
public static final String NOTIFICATION_SMALL_ICON_ID = "notificationSmallIconId";
public static final String NOTIFICATION_SOUND = "notificationSound";
public static final String HIDE_CONTENT = "hideContent";
public static final String LEDARGB = "ledargb";
public static final String LEDONMS = "ledonms";
public static final String LEDOFFMS = "ledoffms";
public static final String TITLE_ONLY_SHOW_APP_NAME = "titleOnlyShowAppName";
public static final String NOTIFICATION_FOLDED = "notificationFolded";
public static final String NOTIFICATION_FOLD_TYPE = "notificationFoldType";
public static final String NOTIFICATION_ENTRANCE = "notificationEntrance";
public static final String NOTIFICATION_COLOR = "notificationColor";
/**************************no disturb end************************************/
public static void setMsgIgnore(boolean enable) {
saveBoolean(KEY_MSG_IGNORE, enable);
}
public static boolean getMsgIgnore() {
return getBoolean(KEY_MSG_IGNORE, false);
}
public static void setNotificationToggle(boolean on) {
saveBoolean(KEY_SB_NOTIFY_TOGGLE, on);
}
public static boolean getNotificationToggle() {
return getBoolean(KEY_SB_NOTIFY_TOGGLE, true);
}
public static void setRingToggle(boolean on) {
saveBoolean(KEY_RING_TOGGLE, on);
}
public static boolean getRingToggle() {
return getBoolean(KEY_RING_TOGGLE, true);
}
public static void setVibrateToggle(boolean on) {
saveBoolean(KEY_VIBRATE_TOGGLE, on);
}
public static boolean getVibrateToggle() {
return getBoolean(KEY_VIBRATE_TOGGLE, true);
}
public static void setLedToggle(boolean on) {
saveBoolean(KEY_LED_TOGGLE, on);
}
public static boolean getLedToggle() {
return getBoolean(KEY_LED_TOGGLE, true);
}
public static boolean getNoticeContentToggle() {
return getBoolean(KEY_NOTICE_CONTENT_TOGGLE, false);
}
public static void setNoticeContentToggle(boolean on) {
saveBoolean(KEY_NOTICE_CONTENT_TOGGLE, on);
}
public static boolean isDeleteFriendAndDeleteAlias() {
return getBoolean(KEY_DELETE_FRIEND_AND_DELETE_ALIAS, false);
}
public static void setDeleteFriendAndDeleteAlias(boolean on) {
saveBoolean(KEY_DELETE_FRIEND_AND_DELETE_ALIAS, on);
}
public static void setDownTimeToggle(boolean on) {
saveBoolean(KEY_DOWNTIME_TOGGLE, on);
}
public static boolean getDownTimeToggle() {
return getBoolean(KEY_DOWNTIME_TOGGLE, false);
}
public static void setStatusConfig(StatusBarNotificationConfig config) {
saveStatusBarNotificationConfig(KEY_STATUS_BAR_NOTIFICATION_CONFIG, config);
}
public static StatusBarNotificationConfig getStatusConfig() {
return getConfig(KEY_STATUS_BAR_NOTIFICATION_CONFIG);
}
public static void setTeamAnnounceClosed(String teamId, boolean closed) {
saveBoolean(KEY_TEAM_ANNOUNCE_CLOSED + teamId, closed);
}
public static boolean getTeamAnnounceClosed(String teamId) {
return getBoolean(KEY_TEAM_ANNOUNCE_CLOSED + teamId, false);
}
public static void setOnlineStateSubsTime(long time) {
saveLong(KEY_SUBSCRIBE_TIME, time);
}
public static long getOnlineStateSubsTime() {
return getLong(KEY_SUBSCRIBE_TIME, 0);
}
private static StatusBarNotificationConfig getConfig(String key) {
StatusBarNotificationConfig config = new StatusBarNotificationConfig();
String jsonString = getSharedPreferences().getString(key, "");
try {
JSONObject jsonObject = JSONObject.parseObject(jsonString);
if (jsonObject == null) {
return null;
}
config.downTimeBegin = jsonObject.getString(DOWN_TIME_BEGIN);
config.downTimeEnd = jsonObject.getString(DOWN_TIME_END);
config.downTimeToggle = jsonObject.getBoolean(DOWN_TIME_TOGGLE);
Boolean downTimeEnableNotification = jsonObject.getBoolean(DOWN_TIME_ENABLE_NOTIFICATION);
config.downTimeEnableNotification = downTimeEnableNotification == null ? true : downTimeEnableNotification;
Boolean ring = jsonObject.getBoolean(RING);
config.ring = ring == null ? true : ring;
Boolean vibrate = jsonObject.getBoolean(VIBRATE);
config.vibrate = vibrate == null ? true : vibrate;
config.notificationSmallIconId = jsonObject.getIntValue(NOTIFICATION_SMALL_ICON_ID);
config.notificationSound = jsonObject.getString(NOTIFICATION_SOUND);
config.hideContent = jsonObject.getBooleanValue(HIDE_CONTENT);
config.ledARGB = jsonObject.getIntValue(LEDARGB);
config.ledOnMs = jsonObject.getIntValue(LEDONMS);
config.ledOffMs = jsonObject.getIntValue(LEDOFFMS);
config.titleOnlyShowAppName = jsonObject.getBooleanValue(TITLE_ONLY_SHOW_APP_NAME);
Boolean notificationFolded = jsonObject.getBoolean(NOTIFICATION_FOLDED);
config.notificationFolded = notificationFolded == null ? true : notificationFolded;
Integer notificationFoldType = jsonObject.getInteger(NOTIFICATION_FOLD_TYPE);
config.notificationFoldStyle = notificationFoldType == null ? null : NotificationFoldStyle.value(notificationFoldType);
if( jsonObject.getString(NOTIFICATION_ENTRANCE)!=null)
{
config.notificationEntrance = (Class<? extends Activity>) Class.forName(
jsonObject.getString(NOTIFICATION_ENTRANCE));
}
config.notificationColor = jsonObject.getInteger(NOTIFICATION_COLOR);
} catch (Exception e) {
e.printStackTrace();
}
return config;
}
private static void saveStatusBarNotificationConfig(String key, StatusBarNotificationConfig config) {
SharedPreferences.Editor editor = getSharedPreferences().edit();
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put(DOWN_TIME_BEGIN, config.downTimeBegin);
jsonObject.put(DOWN_TIME_END, config.downTimeEnd);
jsonObject.put(DOWN_TIME_TOGGLE, config.downTimeToggle);
jsonObject.put(DOWN_TIME_ENABLE_NOTIFICATION, config.downTimeEnableNotification);
jsonObject.put(RING, config.ring);
jsonObject.put(VIBRATE, config.vibrate);
jsonObject.put(NOTIFICATION_SMALL_ICON_ID, config.notificationSmallIconId);
jsonObject.put(NOTIFICATION_SOUND, config.notificationSound);
jsonObject.put(HIDE_CONTENT, config.hideContent);
jsonObject.put(LEDARGB, config.ledARGB);
jsonObject.put(LEDONMS, config.ledOnMs);
jsonObject.put(LEDOFFMS, config.ledOffMs);
jsonObject.put(TITLE_ONLY_SHOW_APP_NAME, config.titleOnlyShowAppName);
jsonObject.put(NOTIFICATION_FOLDED, config.notificationFolded);
jsonObject.put(NOTIFICATION_FOLD_TYPE, config.notificationFoldStyle.getValue());
if (config.notificationEntrance != null) {
jsonObject.put(NOTIFICATION_ENTRANCE, config.notificationEntrance.getName());
}
jsonObject.put(NOTIFICATION_COLOR, config.notificationColor);
} catch (Exception e) {
e.printStackTrace();
}
editor.putString(key, jsonObject.toString());
editor.commit();
}
private static boolean getBoolean(String key, boolean value) {
return getSharedPreferences().getBoolean(key, value);
}
private static void saveBoolean(String key, boolean value) {
SharedPreferences.Editor editor = getSharedPreferences().edit();
editor.putBoolean(key, value);
editor.commit();
}
private static void saveInt(String key, int value) {
SharedPreferences.Editor editor = getSharedPreferences().edit();
editor.putInt(key, value);
editor.commit();
}
private static int getInt(String key, int value) {
return getSharedPreferences().getInt(key, value);
}
private static void saveLong(String key, long value) {
SharedPreferences.Editor editor = getSharedPreferences().edit();
editor.putLong(key, value);
editor.commit();
}
private static long getLong(String key, long value) {
return getSharedPreferences().getLong(key, value);
}
static SharedPreferences getSharedPreferences() {
return DemoCache.getContext().getSharedPreferences("Demo." + DemoCache.getAccount(), Context.MODE_PRIVATE);
}
}
@@ -0,0 +1,11 @@
package cn.shangyu.gdxzExpert.netease.constants;
/**
* Created by hzsunyj on 2019-09-03.
*/
public interface EnterMode {
int NORMAL = 0;
int INDEPENDENT = 1;
}
@@ -0,0 +1,19 @@
package cn.shangyu.gdxzExpert.netease.constants;
/**
* Created by hzsunyj on 2019-09-03.
*/
public interface Extras {
String MODE= "mode";
String APP_KEY = "app_key";
String ACCOUNT = "account";
String PWD = "pwd";
String ROOM_ID = "room_id";
String LINK = "link";
}
@@ -0,0 +1,38 @@
package cn.shangyu.gdxzExpert.netease.contact;
import android.content.Context;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.model.contact.ContactEventListener;
/**
* UIKit联系人列表定制展示类
* <p/>
* Created by huangjun on 2015/9/11.
*/
public class ContactHelper {
public static void init() {
setContactEventListener();
}
private static void setContactEventListener() {
NimUIKit.setContactEventListener(new ContactEventListener() {
@Override
public void onItemClick(Context context, String account) {
UserProfileActivity.start(context, account);
}
@Override
public void onItemLongClick(Context context, String account) {
}
@Override
public void onAvatarClick(Context context, String account) {
UserProfileActivity.start(context, account);
}
});
}
}
@@ -0,0 +1,135 @@
package cn.shangyu.gdxzExpert.netease.contact;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.netease.nim.uikit.common.http.NimHttpClient;
import com.netease.nim.uikit.common.util.string.MD5;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import cn.shangyu.gdxzExpert.netease.DemoCache;
import cn.shangyu.gdxzExpert.netease.config.DemoServers;
/**
* 通讯录数据获取协议的实现
* <p/>
* Created by huangjun on 2015/3/6.
*/
public class ContactHttpClient {
private static final String TAG = "ContactHttpClient";
// code
private static final int RESULT_CODE_SUCCESS = 200;
// api
private static final String API_NAME_REGISTER = "createDemoUser";
// header
private static final String HEADER_KEY_APP_KEY = "appkey";
private static final String HEADER_CONTENT_TYPE = "Content-Type";
private static final String HEADER_USER_AGENT = "User-Agent";
// request
private static final String REQUEST_USER_NAME = "username";
private static final String REQUEST_NICK_NAME = "nickname";
private static final String REQUEST_PASSWORD = "password";
// result
private static final String RESULT_KEY_RES = "res";
private static final String RESULT_KEY_ERROR_MSG = "errmsg";
public interface ContactHttpCallback<T> {
void onSuccess(T t);
void onFailed(int code, String errorMsg);
}
private static ContactHttpClient instance;
public static synchronized ContactHttpClient getInstance() {
if (instance == null) {
instance = new ContactHttpClient();
}
return instance;
}
private ContactHttpClient() {
NimHttpClient.getInstance().init(DemoCache.getContext());
}
/**
* 向应用服务器创建账号(注册账号)
* 由应用服务器调用WEB SDK接口将新注册的用户数据同步到云信服务器
*/
public void register(String account, String nickName, String password, final ContactHttpCallback<Void> callback) {
String url = DemoServers.apiServer() + API_NAME_REGISTER;
password = MD5.getStringMD5(password);
try {
nickName = URLEncoder.encode(nickName, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Map<String, String> headers = new HashMap<>(1);
String appKey = readAppKey();
headers.put(HEADER_CONTENT_TYPE, "application/x-www-form-urlencoded; charset=utf-8");
headers.put(HEADER_USER_AGENT, "nim_demo_android");
headers.put(HEADER_KEY_APP_KEY, appKey);
StringBuilder body = new StringBuilder();
body.append(REQUEST_USER_NAME).append("=").append(account.toLowerCase()).append("&")
.append(REQUEST_NICK_NAME).append("=").append(nickName).append("&")
.append(REQUEST_PASSWORD).append("=").append(password);
String bodyString = body.toString();
NimHttpClient.getInstance().execute(url, headers, bodyString, new NimHttpClient.NimHttpCallback() {
@Override
public void onResponse(String response, int code, Throwable exception) {
if (code != 200 || exception != null) {
String errMsg = exception != null ? exception.getMessage() : "null";
// LogUtil.e(TAG, "register failed : code = " + code + ", errorMsg = " + errMsg);
if (callback != null) {
callback.onFailed(code, errMsg);
}
return;
}
try {
JSONObject resObj = JSONObject.parseObject(response);
int resCode = resObj.getIntValue(RESULT_KEY_RES);
if (resCode == RESULT_CODE_SUCCESS) {
callback.onSuccess(null);
} else {
String error = resObj.getString(RESULT_KEY_ERROR_MSG);
callback.onFailed(resCode, error);
}
} catch (JSONException e) {
callback.onFailed(-1, e.getMessage());
}
}
});
}
private String readAppKey() {
try {
ApplicationInfo appInfo = DemoCache.getContext().
getPackageManager().
getApplicationInfo(DemoCache.getContext().getPackageName(), PackageManager.GET_META_DATA);
if (appInfo != null) {
return appInfo.metaData.getString("com.netease.nim.appKey");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
@@ -0,0 +1,14 @@
package cn.shangyu.gdxzExpert.netease.contact;
/**
* Created by hzxuwen on 2015/9/17.
*/
public class UserConstant {
public static final int KEY_NICKNAME = 1;
public static final int KEY_GENDER = 2;
public static final int KEY_BIRTH = 3;
public static final int KEY_PHONE = 4;
public static final int KEY_EMAIL = 5;
public static final int KEY_SIGNATURE = 6;
public static final int KEY_ALIAS = 7;
}
@@ -0,0 +1,644 @@
package cn.shangyu.gdxzExpert.netease.contact;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.model.SimpleCallback;
import com.netease.nim.uikit.api.model.contact.ContactChangedObserver;
import com.netease.nim.uikit.api.wrapper.NimToolBarOptions;
import com.netease.nim.uikit.business.session.constant.Extras;
import com.netease.nim.uikit.common.ToastHelper;
import com.netease.nim.uikit.common.activity.ToolBarOptions;
import com.netease.nim.uikit.common.activity.UI;
import com.netease.nim.uikit.common.ui.dialog.DialogMaker;
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialog;
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper;
import com.netease.nim.uikit.common.ui.dialog.EasyEditDialog;
import com.netease.nim.uikit.common.ui.imageview.HeadImageView;
import com.netease.nim.uikit.common.ui.widget.SwitchButton;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nim.uikit.common.util.sys.NetworkUtil;
import com.netease.nim.uikit.impl.cache.StickTopCache;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.friend.FriendService;
import com.netease.nimlib.sdk.friend.FriendServiceObserve;
import com.netease.nimlib.sdk.friend.constant.VerifyType;
import com.netease.nimlib.sdk.friend.model.AddFriendData;
import com.netease.nimlib.sdk.friend.model.MuteListChangedNotify;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.msg.model.StickTopSessionInfo;
import com.netease.nimlib.sdk.uinfo.constant.GenderEnum;
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
import java.util.List;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.DemoCache;
import cn.shangyu.gdxzExpert.netease.config.preference.UserPreferences;
import cn.shangyu.gdxzExpert.netease.session.SessionHelper;
import cn.shangyu.gdxzExpert.netease.uinfo.UserInfoHelper;
import static cn.shangyu.gdxzExpert.utils.Constant.general;
/**
* 用户资料页面
* Created by huangjun on 2015/8/11.
*/
public class UserProfileActivity extends UI {
private static final String TAG = UserProfileActivity.class.getSimpleName();
private final boolean FLAG_ADD_FRIEND_DIRECTLY = true; // 是否直接加为好友开关,false为需要好友申请
private final String KEY_BLACK_LIST = "black_list";
private final String KEY_MSG_NOTICE = "msg_notice";
private final String KEY_RECENT_STICKY = "recent_contacts_sticky";
private String account;
// 基本信息
private HeadImageView headImageView;
private TextView nameText;
private ImageView genderImage;
private TextView accountText;
private TextView birthdayText;
private TextView mobileText;
private TextView emailText;
private TextView signatureText;
private RelativeLayout birthdayLayout;
private RelativeLayout phoneLayout;
private RelativeLayout emailLayout;
private RelativeLayout signatureLayout;
private RelativeLayout aliasLayout;
private TextView nickText;
// 开关
private ViewGroup toggleLayout;
private Button addFriendBtn;
private Button removeFriendBtn;
private Button chatBtn;
private SwitchButton blackSwitch;
private SwitchButton noticeSwitch;
private SwitchButton stickySwitch;
public static void start(Context context, String account) {
Intent intent = new Intent();
intent.setClass(context, UserProfileActivity.class);
intent.putExtra(Extras.EXTRA_ACCOUNT, account);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_profile_activity);
account = getIntent().getStringExtra(Extras.EXTRA_ACCOUNT);
if (TextUtils.isEmpty(account)) {
ToastHelper.showToast(UserProfileActivity.this, "传入的帐号为空");
finish();
return;
}
ToolBarOptions options = new NimToolBarOptions();
options.titleId = com.netease.nim.uikit.R.string.user_profile;
setToolBar(R.id.toolbar, options);
initActionbar();
findViews();
registerObserver(true);
}
@Override
protected void onResume() {
super.onResume();
updateUserInfo();
updateToggleView();
}
@Override
protected void onDestroy() {
super.onDestroy();
registerObserver(false);
}
private void registerObserver(boolean register) {
NimUIKit.getContactChangedObservable().registerObserver(friendDataChangedObserver, register);
NIMClient.getService(FriendServiceObserve.class).observeMuteListChangedNotify(muteListChangedNotifyObserver,
register);
}
Observer<MuteListChangedNotify> muteListChangedNotifyObserver = new Observer<MuteListChangedNotify>() {
@Override
public void onEvent(MuteListChangedNotify notify) {
setToggleBtn(noticeSwitch, !notify.isMute());
}
};
ContactChangedObserver friendDataChangedObserver = new ContactChangedObserver() {
@Override
public void onAddedOrUpdatedFriends(List<String> account) {
updateUserOperatorView();
}
@Override
public void onDeletedFriends(List<String> account) {
updateUserOperatorView();
}
@Override
public void onAddUserToBlackList(List<String> account) {
updateUserOperatorView();
}
@Override
public void onRemoveUserFromBlackList(List<String> account) {
updateUserOperatorView();
}
};
private void findViews() {
headImageView = findView(R.id.user_head_image);
nameText = findView(R.id.user_name);
genderImage = findView(R.id.gender_img);
accountText = findView(R.id.user_account);
toggleLayout = findView(R.id.toggle_layout);
addFriendBtn = findView(R.id.add_buddy);
chatBtn = findView(R.id.begin_chat);
removeFriendBtn = findView(R.id.remove_buddy);
birthdayLayout = findView(R.id.birthday);
nickText = findView(R.id.user_nick);
birthdayText = birthdayLayout.findViewById(com.netease.nim.uikit.R.id.value);
phoneLayout = findView(R.id.phone);
mobileText = phoneLayout.findViewById(com.netease.nim.uikit.R.id.value);
emailLayout = findView(R.id.email);
emailText = emailLayout.findViewById(com.netease.nim.uikit.R.id.value);
signatureLayout = findView(R.id.signature);
signatureText = signatureLayout.findViewById(com.netease.nim.uikit.R.id.value);
aliasLayout = findView(R.id.alias);
((TextView) birthdayLayout.findViewById(R.id.attribute)).setText(com.netease.nim.uikit.R.string.birthday);
((TextView) phoneLayout.findViewById(R.id.attribute)).setText(com.netease.nim.uikit.R.string.phone);
((TextView) emailLayout.findViewById(R.id.attribute)).setText(com.netease.nim.uikit.R.string.email);
((TextView) signatureLayout.findViewById(R.id.attribute)).setText(com.netease.nim.uikit.R.string.signature);
((TextView) aliasLayout.findViewById(R.id.attribute)).setText(com.netease.nim.uikit.R.string.alias);
addFriendBtn.setOnClickListener(onClickListener);
chatBtn.setOnClickListener(onClickListener);
removeFriendBtn.setOnClickListener(onClickListener);
// aliasLayout.setOnClickListener(v -> UserProfileEditItemActivity.startActivity(UserProfileActivity.this, UserConstant.KEY_ALIAS, account));
}
private void initActionbar() {
TextView toolbarView = findView(com.netease.nim.uikit.R.id.action_bar_right_clickable_textview);
if (!TextUtils.equals(account, DemoCache.getAccount())) {
toolbarView.setVisibility(View.GONE);
return;
} else {
toolbarView.setVisibility(View.VISIBLE);
}
toolbarView.setText(com.netease.nim.uikit.R.string.edit);
// toolbarView.setOnClickListener(v -> UserProfileSettingActivity.start(UserProfileActivity.this, account));
}
private void setToggleBtn(SwitchButton btn, boolean isChecked) {
btn.setCheck(isChecked);
}
private void updateUserInfo() {
if (NimUIKit.getUserInfoProvider().getUserInfo(account) != null) {
updateUserInfoView();
return;
}
NimUIKit.getUserInfoProvider().getUserInfoAsync(account, (SimpleCallback<NimUserInfo>) (success, result, code) -> updateUserInfoView());
}
private void updateUserInfoView() {
accountText.setText("帐号:" + account);
headImageView.loadBuddyAvatar(account);
if (TextUtils.equals(account, DemoCache.getAccount())) {
nameText.setText(UserInfoHelper.getUserName(account));
}
final NimUserInfo userInfo = (NimUserInfo) NimUIKit.getUserInfoProvider().getUserInfo(account);
if (userInfo == null) {
LogUtil.e(TAG, "userInfo is null when updateUserInfoView");
return;
}
if (userInfo.getGenderEnum() == GenderEnum.MALE) {
genderImage.setVisibility(View.VISIBLE);
genderImage.setBackgroundResource(com.netease.nim.uikit.R.drawable.nim_male);
} else if (userInfo.getGenderEnum() == GenderEnum.FEMALE) {
genderImage.setVisibility(View.VISIBLE);
genderImage.setBackgroundResource(R.drawable.nim_female);
} else {
genderImage.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(userInfo.getBirthday())) {
birthdayLayout.setVisibility(View.VISIBLE);
birthdayText.setText(userInfo.getBirthday());
} else {
birthdayLayout.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(userInfo.getMobile())) {
phoneLayout.setVisibility(View.VISIBLE);
mobileText.setText(userInfo.getMobile());
} else {
phoneLayout.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(userInfo.getEmail())) {
emailLayout.setVisibility(View.VISIBLE);
emailText.setText(userInfo.getEmail());
} else {
emailLayout.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(userInfo.getSignature())) {
signatureLayout.setVisibility(View.VISIBLE);
signatureText.setText(userInfo.getSignature());
} else {
signatureLayout.setVisibility(View.GONE);
}
}
private void updateUserOperatorView() {
chatBtn.setVisibility(View.VISIBLE);
if (NIMClient.getService(FriendService.class).isMyFriend(account)) {
removeFriendBtn.setVisibility(View.VISIBLE);
addFriendBtn.setVisibility(View.GONE);
updateAlias(true);
} else {
addFriendBtn.setVisibility(View.VISIBLE);
removeFriendBtn.setVisibility(View.GONE);
updateAlias(false);
}
}
private void updateToggleView() {
if (DemoCache.getAccount() != null && !DemoCache.getAccount().equals(account)) {
boolean black = NIMClient.getService(FriendService.class).isInBlackList(account);
boolean notice = NIMClient.getService(FriendService.class).isNeedMessageNotify(account);
if (blackSwitch == null) {
blackSwitch = addToggleItemView(KEY_BLACK_LIST, com.netease.nim.uikit.R.string.black_list, black);
} else {
setToggleBtn(blackSwitch, black);
}
if (noticeSwitch == null) {
noticeSwitch = addToggleItemView(KEY_MSG_NOTICE, com.netease.nim.uikit.R.string.msg_notice, notice);
} else {
setToggleBtn(noticeSwitch, notice);
}
if (NIMClient.getService(FriendService.class).isMyFriend(account)) {
RecentContact recentContact = NIMClient.getService(MsgService.class).queryRecentContact(account,
SessionTypeEnum.P2P);
boolean isSticky = StickTopCache.isStickTop(account, SessionTypeEnum.P2P);
if (stickySwitch == null) {
stickySwitch = addToggleItemView(KEY_RECENT_STICKY, com.netease.nim.uikit.R.string.recent_sticky, isSticky);
} else {
setToggleBtn(stickySwitch, isSticky);
}
}
updateUserOperatorView();
}
}
private SwitchButton addToggleItemView(String key, int titleResId, boolean initState) {
ViewGroup vp = (ViewGroup) getLayoutInflater().inflate(com.netease.nim.uikit.R.layout.nim_user_profile_toggle_item, null);
ViewGroup.LayoutParams vlp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
(int) getResources()
.getDimension(com.netease.nim.uikit.R.dimen.isetting_item_height));
vp.setLayoutParams(vlp);
TextView titleText = vp.findViewById(com.netease.nim.uikit.R.id.user_profile_title);
titleText.setText(titleResId);
SwitchButton switchButton = vp.findViewById(com.netease.nim.uikit.R.id.user_profile_toggle);
switchButton.setCheck(initState);
switchButton.setOnChangedListener(onChangedListener);
switchButton.setTag(key);
toggleLayout.addView(vp);
return switchButton;
}
private void updateAlias(boolean isFriend) {
if (isFriend) {
aliasLayout.setVisibility(View.VISIBLE);
aliasLayout.findViewById(com.netease.nim.uikit.R.id.arrow_right).setVisibility(View.VISIBLE);
String alias = NimUIKit.getContactProvider().getAlias(account);
String name = UserInfoHelper.getUserName(account);
if (!TextUtils.isEmpty(alias)) {
nickText.setVisibility(View.VISIBLE);
nameText.setText(alias);
nickText.setText("昵称:" + name);
} else {
nickText.setVisibility(View.GONE);
nameText.setText(name);
}
} else {
aliasLayout.setVisibility(View.GONE);
aliasLayout.findViewById(com.netease.nim.uikit.R.id.arrow_right).setVisibility(View.GONE);
nickText.setVisibility(View.GONE);
nameText.setText(UserInfoHelper.getUserName(account));
}
}
private SwitchButton.OnChangedListener onChangedListener = (v, checkState) -> {
final String key = (String) v.getTag();
if (KEY_RECENT_STICKY.equals(key)) {
updateSticky(checkState);
}else if (key.equals(KEY_BLACK_LIST)) {
updateBlack(checkState);
} else if (key.equals(KEY_MSG_NOTICE)) {
updateNotice(checkState);
}
};
private void updateNotice(boolean checkState) {
if (!NetworkUtil.isNetAvailable(UserProfileActivity.this)) {
ToastHelper.showToast(UserProfileActivity.this, com.netease.nim.uikit.R.string.network_is_not_available);
noticeSwitch.setCheck(!checkState);
return;
}
NIMClient.getService(FriendService.class).setMessageNotify(account, checkState).setCallback(
new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
if (checkState) {
ToastHelper.showToast(UserProfileActivity.this, "开启消息提醒成功");
} else {
ToastHelper.showToast(UserProfileActivity.this, "关闭消息提醒成功");
}
}
@Override
public void onFailed(int code) {
if (code == 408) {
ToastHelper.showToast(UserProfileActivity.this, com.netease.nim.uikit.R.string.network_is_not_available);
} else {
ToastHelper.showToast(UserProfileActivity.this, "on failed:" + code);
}
noticeSwitch.setCheck(!checkState);
}
@Override
public void onException(Throwable exception) {
}
});
}
private void updateBlack(boolean checkState) {
if (!NetworkUtil.isNetAvailable(UserProfileActivity.this)) {
ToastHelper.showToast(UserProfileActivity.this, com.netease.nim.uikit.R.string.network_is_not_available);
blackSwitch.setCheck(!checkState);
return;
}
if (checkState) {
NIMClient.getService(FriendService.class).addToBlackList(account).setCallback(
new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
ToastHelper.showToast(UserProfileActivity.this, "加入黑名单成功");
}
@Override
public void onFailed(int code) {
if (code == 408) {
ToastHelper.showToast(UserProfileActivity.this, com.netease.nim.uikit.R.string.network_is_not_available);
} else {
ToastHelper.showToast(UserProfileActivity.this, "on failed:" + code);
}
blackSwitch.setCheck(false);
}
@Override
public void onException(Throwable exception) {
}
});
} else {
NIMClient.getService(FriendService.class).removeFromBlackList(account).setCallback(
new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
ToastHelper.showToast(UserProfileActivity.this, "移除黑名单成功");
}
@Override
public void onFailed(int code) {
if (code == 408) {
ToastHelper.showToast(UserProfileActivity.this, com.netease.nim.uikit.R.string.network_is_not_available);
} else {
ToastHelper.showToast(UserProfileActivity.this, "on failed:" + code);
}
blackSwitch.setCheck(true);
}
@Override
public void onException(Throwable exception) {
}
});
}
}
private void updateSticky(boolean checkState) {
MsgService msgService = NIMClient.getService(MsgService.class);
//查询之前是不是存在会话记录
RecentContact recentContactFromDB = msgService.queryRecentContact(account, SessionTypeEnum.P2P);
//置顶
if (checkState) {
//如果之前不存在,创建一条空的会话记录
final RecentContact recent = recentContactFromDB != null ? recentContactFromDB :
msgService.createEmptyRecentContact(account, SessionTypeEnum.P2P, 0, System.currentTimeMillis(), true);
// 执行置顶操作
msgService.addStickTopSession(account, SessionTypeEnum.P2P, "").setCallback(new RequestCallbackWrapper<StickTopSessionInfo>() {
@Override
public void onResult(int code, StickTopSessionInfo result, Throwable exception) {
if (ResponseCode.RES_SUCCESS == code) {
StickTopCache.recordStickTop(result, true);
msgService.updateRecentAndNotify(recent);
}
}
});
}
//取消置顶
else {
msgService.removeStickTopSession(account, SessionTypeEnum.P2P, "").setCallback(new RequestCallbackWrapper<Void>() {
@Override
public void onResult(int code, Void result, Throwable exception) {
if (ResponseCode.RES_SUCCESS == code && recentContactFromDB != null) {
StickTopCache.recordStickTop(account, SessionTypeEnum.P2P, false);
msgService.updateRecentAndNotify(recentContactFromDB);
}
}
});
}
}
private View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v == addFriendBtn) {
if (FLAG_ADD_FRIEND_DIRECTLY) {
doAddFriend(null, true); // 直接加为好友
} else {
onAddFriendByVerify(); // 发起好友验证请求
}
} else if (v == removeFriendBtn) {
onRemoveFriend();
} else if (v == chatBtn) {
onChat();
}
}
};
/**
* 通过验证方式添加好友
*/
private void onAddFriendByVerify() {
final EasyEditDialog requestDialog = new EasyEditDialog(this);
requestDialog.setEditTextMaxLength(32);
requestDialog.setTitle(getString(com.netease.nim.uikit.R.string.add_friend_verify_tip));
requestDialog.addNegativeButtonListener(com.netease.nim.uikit.R.string.cancel, v -> requestDialog.dismiss());
requestDialog.addPositiveButtonListener(com.netease.nim.uikit.R.string.send, v -> {
requestDialog.dismiss();
String msg = requestDialog.getEditMessage();
doAddFriend(msg, false);
});
requestDialog.setOnCancelListener(dialog -> {
});
requestDialog.show();
}
private void doAddFriend(String msg, boolean addDirectly) {
if (!NetworkUtil.isNetAvailable(this)) {
ToastHelper.showToast(UserProfileActivity.this, com.netease.nim.uikit.R.string.network_is_not_available);
return;
}
if (!TextUtils.isEmpty(account) && account.equals(DemoCache.getAccount())) {
ToastHelper.showToast(UserProfileActivity.this, "不能加自己为好友");
return;
}
final VerifyType verifyType = addDirectly ? VerifyType.DIRECT_ADD : VerifyType.VERIFY_REQUEST;
DialogMaker.showProgressDialog(this, "", true);
NIMClient.getService(FriendService.class).addFriend(new AddFriendData(account, verifyType, msg)).setCallback(
new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
DialogMaker.dismissProgressDialog();
updateUserOperatorView();
if (VerifyType.DIRECT_ADD == verifyType) {
ToastHelper.showToast(UserProfileActivity.this, "添加好友成功");
} else {
ToastHelper.showToast(UserProfileActivity.this, "添加好友请求发送成功");
}
}
@Override
public void onFailed(int code) {
DialogMaker.dismissProgressDialog();
if (code == 408) {
ToastHelper.showToast(UserProfileActivity.this, com.netease.nim.uikit.R.string.network_is_not_available);
} else {
ToastHelper.showToast(UserProfileActivity.this, "on failed:" + code);
}
}
@Override
public void onException(Throwable exception) {
DialogMaker.dismissProgressDialog();
}
});
Log.i(TAG, "onAddFriendByVerify");
}
private void onRemoveFriend() {
Log.i(TAG, "onRemoveFriend");
if (!NetworkUtil.isNetAvailable(this)) {
ToastHelper.showToast(UserProfileActivity.this, com.netease.nim.uikit.R.string.network_is_not_available);
return;
}
EasyAlertDialog dialog = EasyAlertDialogHelper.createOkCancelDiolag(this, getString(com.netease.nim.uikit.R.string.remove_friend), getString(com.netease.nim.uikit.R.string.remove_friend_tip), true, new EasyAlertDialogHelper.OnDialogActionListener() {
@Override
public void doCancelAction() {
}
@Override
public void doOkAction() {
DialogMaker.showProgressDialog(UserProfileActivity.this, "", true);
boolean deleteAlias = UserPreferences.isDeleteFriendAndDeleteAlias();
NIMClient.getService(FriendService.class).deleteFriend(account, deleteAlias).setCallback(
new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
DialogMaker.dismissProgressDialog();
ToastHelper.showToast(UserProfileActivity.this, com.netease.nim.uikit.R.string.remove_friend_success);
finish();
}
@Override
public void onFailed(int code) {
DialogMaker.dismissProgressDialog();
if (code == 408) {
ToastHelper.showToast(UserProfileActivity.this, com.netease.nim.uikit.R.string.network_is_not_available);
} else {
ToastHelper.showToast(UserProfileActivity.this, "on failed:" + code);
}
}
@Override
public void onException(Throwable exception) {
DialogMaker.dismissProgressDialog();
}
});
}
});
if (!isFinishing() && !isDestroyedCompatible()) {
dialog.show();
}
}
private void onChat() {
Log.i(TAG, "onChat");
SessionHelper.startP2PSession(this, account,general,"");
}
}
@@ -0,0 +1,48 @@
package cn.shangyu.gdxzExpert.netease.contact;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.uinfo.UserService;
import com.netease.nimlib.sdk.uinfo.constant.UserInfoFieldEnum;
import java.util.HashMap;
import java.util.Map;
/**
* Created by hzxuwen on 2015/9/17.
*/
public class UserUpdateHelper {
private static final String TAG = UserUpdateHelper.class.getSimpleName();
/**
* 更新用户资料
*/
public static void update(final UserInfoFieldEnum field, final Object value, RequestCallbackWrapper<Void> callback) {
Map<UserInfoFieldEnum, Object> fields = new HashMap<>(1);
fields.put(field, value);
update(fields, callback);
}
private static void update(final Map<UserInfoFieldEnum, Object> fields, final RequestCallbackWrapper<Void> callback) {
NIMClient.getService(UserService.class).updateUserInfo(fields).setCallback(new RequestCallbackWrapper<Void>() {
@Override
public void onResult(int code, Void result, Throwable exception) {
if (code == ResponseCode.RES_SUCCESS) {
LogUtil.i(TAG, "update userInfo success, update fields count=" + fields.size());
} else {
if (exception != null) {
// ToastHelper.showToast(DemoCache.getContext(), R.string.user_info_update_failed);
LogUtil.i(TAG, "update userInfo failed, exception=" + exception.getMessage());
}
}
if (callback != null) {
callback.onResult(code, result, exception);
}
}
});
}
}
@@ -0,0 +1,45 @@
package cn.shangyu.gdxzExpert.netease.event;
import android.text.TextUtils;
import com.netease.nim.uikit.api.model.main.OnlineStateContentProvider;
import cn.shangyu.gdxzExpert.netease.DemoCache;
/**
* Created by hzchenkang on 2017/3/31.
*/
public class DemoOnlineStateContentProvider implements OnlineStateContentProvider {
@Override
public String getSimpleDisplay(String account) {
String content = getDisplayContent(account, true);
if (!TextUtils.isEmpty(content)) {
content = "[" + content + "]";
}
return content;
}
@Override
public String getDetailDisplay(String account) {
return getDisplayContent(account, false);
}
private String getDisplayContent(String account, boolean simple) {
if (account == null || account.equals(DemoCache.getAccount())) {
return "";
}
// 被过滤掉的直接显示在线,如机器人
if (OnlineStateEventSubscribe.subscribeFilter(account)) {
return "在线";
}
// 检查是否订阅过
OnlineStateEventManager.checkSubscribe(account);
OnlineState onlineState = OnlineStateEventCache.getOnlineState(account);
return OnlineStateEventManager.getOnlineClientContent(DemoCache.getContext(), onlineState, simple);
}
}
@@ -0,0 +1,92 @@
package cn.shangyu.gdxzExpert.netease.event;
import com.netease.nimlib.sdk.event.model.Event;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by hzchenkang on 2017/4/10.
*/
public class EventFilter {
private Map<KeyModel, Long> timeFilter;
private EventFilter() {
timeFilter = new HashMap<>();
}
private static class Instance {
private static EventFilter instance = new EventFilter();
}
public static EventFilter getInstance() {
return Instance.instance;
}
/**
* 一般地,先发布事件先下发,但是可能存在同一事件先后顺序错乱的情况,因为事件以最后时间为准,因此这里过滤掉无效旧的事件
*
* @param events
* @return
*/
public List<Event> filterOlderEvent(List<Event> events) {
if (events == null || events.isEmpty()) {
return null;
}
List<Event> results = new ArrayList<>();
for (Event event : events) {
KeyModel key = new KeyModel(event.getEventType(), event.getPublisherAccount());
long eventTime = event.getPublishTime();
if (timeFilter.containsKey(key)) {
long lastEventTime = timeFilter.get(key);
if (eventTime < lastEventTime) {
continue;
}
}
timeFilter.put(key, eventTime);
results.add(event);
}
return results;
}
private static class KeyModel {
private int eventType;
private String id = "";
public KeyModel(int eventType, String id) {
this.eventType = eventType;
this.id = id;
}
@Override
public int hashCode() {
if (id == null) {
return eventType;
} else {
return eventType + 32 * id.hashCode();
}
}
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof KeyModel)) {
return false;
}
KeyModel other = (KeyModel) o;
if (eventType == other.eventType) {
if (id == null) {
return other.id == null;
} else {
return id.equals(other.id);
}
} else {
return false;
}
}
}
}
@@ -0,0 +1,57 @@
package cn.shangyu.gdxzExpert.netease.event;
public enum NetStateCode {
/**
* 未知
*/
Unkown(0),
/**
* wifi
*/
Wifi(1),
/**
* WWAN
*/
WWAN(2),
/**
* 2G
*/
_2G(3),
/**
* 3G
*/
_3G(4),
/**
* 4G
*/
_4G(5);
private int value;
NetStateCode(int netState) {
this.value = netState;
}
public int getValue() {
return value;
}
public static NetStateCode getNetStateCode(int value) {
switch (value) {
case 0:
return Unkown;
case 1:
return Wifi;
case 2:
return WWAN;
case 3:
return _2G;
case 4:
return _3G;
case 5:
return _4G;
default:
return null;
}
}
}
@@ -0,0 +1,62 @@
package cn.shangyu.gdxzExpert.netease.event;
/**
* 在线状态
*/
public class OnlineState {
/**
* 客户端类型,参照 {@link com.netease.nimlib.sdk.auth.ClientType}
*/
private int onlineClient;
/**
* 网络状态,WIFI,4G,3G,2G
*/
private NetStateCode netState;
/**
* 在线状态,0 在线 1 忙碌 2 离开
*/
private OnlineStateCode onlineState;
public OnlineState(int onlineClient, int netState, int onlineState) {
this.onlineClient = onlineClient;
this.netState = NetStateCode.getNetStateCode(netState);
this.onlineState = OnlineStateCode.getOnlineStateCode(onlineState);
}
public OnlineState(int onlineClient, NetStateCode netState, OnlineStateCode onlineState) {
this.onlineClient = onlineClient;
this.netState = netState;
this.onlineState = onlineState;
}
/**
* 获取在线状态
*
* @return onlineState
*/
public OnlineStateCode getOnlineState() {
return onlineState;
}
/**
* 获取在线客户端类型
*
* @return onlineClient
*/
public int getOnlineClient() {
return onlineClient;
}
/**
* 获取网络状态
*
* @return netState
*/
public NetStateCode getNetState() {
return netState;
}
}
@@ -0,0 +1,40 @@
package cn.shangyu.gdxzExpert.netease.event;
public enum OnlineStateCode {
/**
* 在线
*/
Online(0),
/**
* 忙碌
*/
Busy(1),
/**
* 离线
*/
Offline(2);
private int value;
OnlineStateCode(int netState) {
this.value = netState;
}
public int getValue() {
return value;
}
public static OnlineStateCode getOnlineStateCode(int value) {
switch (value) {
case 0:
return Online;
case 1:
return Busy;
case 2:
return Offline;
default:
return null;
}
}
}
@@ -0,0 +1,65 @@
package cn.shangyu.gdxzExpert.netease.event;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Created by hzchenkang on 2017/4/11.
*/
public class OnlineStateEventCache {
private static Map<String, OnlineState> onlineStateCache = new HashMap<>();
// 管理在线状态订阅账号
private static Set<String> subscribeAccounts = new HashSet<>();
public static OnlineState getOnlineState(String account) {
return onlineStateCache.get(account);
}
public static void cacheOnlineState(String account, OnlineState state) {
onlineStateCache.put(account, state);
}
public static void removeOnlineState(List<String> accounts) {
if (accounts != null && !accounts.isEmpty()) {
for (String account : accounts) {
onlineStateCache.remove(account);
}
}
}
public static void addSubsAccounts(List<String> accounts) {
subscribeAccounts.addAll(accounts);
}
public static void addSubsAccount(String accounts) {
subscribeAccounts.add(accounts);
}
public static boolean hasSubscribed(String account) {
return subscribeAccounts.contains(account);
}
public static void removeSubsAccounts(List<String> accounts) {
subscribeAccounts.removeAll(accounts);
}
public static List<String> getSubsAccounts() {
return new ArrayList<>(subscribeAccounts);
}
public static void resetCache() {
onlineStateCache.clear();
subscribeAccounts.clear();
}
public static void clearSubsAccounts() {
subscribeAccounts.clear();
}
}
@@ -0,0 +1,46 @@
package cn.shangyu.gdxzExpert.netease.event;
import android.text.TextUtils;
import org.json.JSONException;
import org.json.JSONObject;
/**
* 在线状态事件扩展字段 config 格式
*/
public class OnlineStateEventConfig {
// 多端在线状态配置解析
public static final String KEY_NET_STATE = "net_state";
public static final String KEY_ONLINE_STATE = "online_state"; //0 在线 1忙碌 2离开";
public static String buildConfig(int netState, int onlineState) {
JSONObject json = new JSONObject();
try {
json.put(KEY_NET_STATE, netState);
json.put(KEY_ONLINE_STATE, onlineState);
} catch (JSONException e) {
e.printStackTrace();
}
return json.toString();
}
public static OnlineState parseConfig(String config, int clientType) {
if (TextUtils.isEmpty(config)) {
return null;
}
OnlineState state = null;
try {
JSONObject json = new JSONObject(config);
int netState = json.getInt(KEY_NET_STATE);
int onlineState = json.getInt(KEY_ONLINE_STATE);
state = new OnlineState(clientType, netState, onlineState);
} catch (JSONException e) {
e.printStackTrace();
}
return state;
}
}
@@ -0,0 +1,450 @@
package cn.shangyu.gdxzExpert.netease.event;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.model.contact.ContactChangedObserver;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nim.uikit.common.util.sys.NetworkUtil;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.StatusCode;
import com.netease.nimlib.sdk.auth.AuthServiceObserver;
import com.netease.nimlib.sdk.auth.ClientType;
import com.netease.nimlib.sdk.event.EventSubscribeService;
import com.netease.nimlib.sdk.event.EventSubscribeServiceObserver;
import com.netease.nimlib.sdk.event.model.Event;
import com.netease.nimlib.sdk.event.model.NimOnlineStateEvent;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.DemoCache;
/**
* 在线状态事件管理
*/
public class OnlineStateEventManager {
/**
* 发布事件有效期7天
*/
private static final long EVENT_EXPIRY = 60 * 60 * 24 * 7;
private static final String NET_TYPE_2G = "2G";
private static final String NET_TYPE_3G = "3G";
private static final String NET_TYPE_4G = "4G";
private static final String NET_TYPE_WIFI = "WiFi";
private static final String UNKNOWN = "未知";
// 已发布的网络状态
private static int pubNetState = -1;
private static boolean enable = false;
public static void init() {
if (!enableOnlineStateEvent()) {
return;
}
registerEventObserver(true);
registerOnlineStatusObserver();
NimUIKit.getContactChangedObservable().registerObserver(observer, true);
registerNetTypeChangeObserver();
}
private static ContactChangedObserver observer = new ContactChangedObserver() {
@Override
public void onAddedOrUpdatedFriends(List<String> accounts) {
if (accounts == null || accounts.isEmpty()) {
return;
}
List<String> subs = new ArrayList<>();
for (String account : accounts) {
if (!OnlineStateEventCache.hasSubscribed(account)) {
subs.add(account);
}
}
LogUtil.ui("added or updated friends subscribe online state " + subs);
OnlineStateEventSubscribe.subscribeOnlineStateEvent(subs, OnlineStateEventSubscribe.SUBSCRIBE_EXPIRY);
}
@Override
public void onDeletedFriends(final List<String> accounts) {
// 如果最近会话里面存在该用户,则不取消订阅
if (accounts == null || accounts.isEmpty()) {
return;
}
NIMClient.getService(MsgService.class).queryRecentContacts().setCallback(new RequestCallbackWrapper<List<RecentContact>>() {
@Override
public void onResult(int code, List<RecentContact> result, Throwable exception) {
// 取消订阅名单
List<String> unSubs = new ArrayList<>();
if (code != ResponseCode.RES_SUCCESS || result == null) {
unSubs = accounts;
} else {
Set<String> recentContactSet = new HashSet<>();
for (RecentContact recentContact : result) {
if (recentContact.getSessionType() == SessionTypeEnum.P2P) {
recentContactSet.add(recentContact.getContactId());
}
}
for (String account : accounts) {
if (!recentContactSet.contains(account)) {
unSubs.add(account);
}
}
}
if (!unSubs.isEmpty()) {
OnlineStateEventSubscribe.unSubscribeOnlineStateEvent(unSubs);
}
}
});
}
@Override
public void onAddUserToBlackList(List<String> account) {
}
@Override
public void onRemoveUserFromBlackList(List<String> account) {
}
};
/**
* 在登陆状态变为已登录之后,发布自己的在线状态,订阅事件
*/
private static void registerOnlineStatusObserver() {
NIMClient.getService(AuthServiceObserver.class).observeOnlineStatus(new Observer<StatusCode>() {
@Override
public void onEvent(StatusCode statusCode) {
if (statusCode != StatusCode.LOGINED) {
return;
}
LogUtil.ui("status change to login so publish state and subscribe");
// 发布自己的在线状态
pubNetState = -1;
publishOnlineStateEvent(false);
// 订阅在线状态,包括好友以及最近联系人
OnlineStateEventSubscribe.initSubscribes();
}
}, true);
}
private static BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo info = cm.getActiveNetworkInfo();
if (info == null || !info.isAvailable()) {
return;
}
LogUtil.ui("BroadcastReceiver CONNECTIVITY_ACTION " + info.getType() + info.getTypeName() + info.getExtraInfo());
if (NIMClient.getStatus() == StatusCode.LOGINED) {
publishOnlineStateEvent(false);
}
}
}
};
private static void registerNetTypeChangeObserver() {
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
DemoCache.getContext().registerReceiver(receiver, filter);
}
/**
* 注册事件观察者
*
* @param register
*/
private static void registerEventObserver(boolean register) {
NIMClient.getService(EventSubscribeServiceObserver.class).observeEventChanged(new Observer<List<Event>>() {
@Override
public void onEvent(List<Event> events) {
// 过滤掉旧的事件
events = EventFilter.getInstance().filterOlderEvent(events);
if (events == null) {
return;
}
// 筛选出在线状态事件
List<Event> onlineStateEvents = new ArrayList<>();
for (int i = 0; i < events.size(); i++) {
Event e = events.get(i);
if (NimOnlineStateEvent.isOnlineStateEvent(e)) {
onlineStateEvents.add(e);
}
}
// 处理在线状态事件
receivedOnlineStateEvents(onlineStateEvents);
}
}, register);
}
/**
* 从事件中获取该账户的多端在线状态信息
*
* @param event
* @return
*/
private static Map<Integer, OnlineState> getOnlineStateFromEvent(Event event) {
if (!NimOnlineStateEvent.isOnlineStateEvent(event)) {
return null;
}
// 解析
List<Integer> clients = NimOnlineStateEvent.getOnlineClients(event);
if (clients == null) {
return null;
}
Map<Integer, OnlineState> onlineStates = new HashMap<>();
for (int i = 0; i < clients.size(); i++) {
int clientType = clients.get(i);
OnlineState state = OnlineStateEventConfig.parseConfig(event.getConfigByClient(clientType), clientType);
if (state == null) {
state = new OnlineState(clientType, NetStateCode.Unkown, OnlineStateCode.Online);
}
onlineStates.put(clientType, state);
}
return onlineStates;
}
/**
* 构建一个在线状态事件
*
* @param netState 当前在线网络状态
* @param syncSelfEnable 是否多端同步
* @param broadcastOnlineOnly 是否只广播给在线用户
* @param expiry 事件有效期,单位秒
* @return event
*/
public static Event buildOnlineStateEvent(int netState, int onlineState, boolean syncSelfEnable, boolean broadcastOnlineOnly, long expiry) {
Event event = new Event(NimOnlineStateEvent.EVENT_TYPE, NimOnlineStateEvent.MODIFY_EVENT_CONFIG, expiry);
event.setSyncSelfEnable(syncSelfEnable);
event.setBroadcastOnlineOnly(broadcastOnlineOnly);
event.setConfig(OnlineStateEventConfig.buildConfig(netState, onlineState));
return event;
}
/**
* 接收到在线状态事件
*
* @param events
*/
private static void receivedOnlineStateEvents(List<Event> events) {
Set<String> changed = new HashSet<String>();
for (Event event : events) {
if (NimOnlineStateEvent.isOnlineStateEvent(event)) {
// 获取优先级最高的在线客户端的状态
OnlineState state = getDisplayOnlineState(event);
changed.add(event.getPublisherAccount());
// 将事件缓存
OnlineStateEventCache.cacheOnlineState(event.getPublisherAccount(), state);
LogUtil.ui("received and cached onlineState of account " + event.getPublisherAccount());
}
}
// 如果 UIKit 使用在线状态功能,则通知在线状态变化
if (NimUIKit.enableOnlineState()) {
NimUIKit.getOnlineStateChangeObservable().notifyOnlineStateChange(changed);
}
}
/**
* 发布自己在线状态
*/
public static void publishOnlineStateEvent(boolean force) {
if (!enable) {
return;
}
int netState = getNetWorkTypeName(DemoCache.getContext());
if (!force && netState == pubNetState) {
return;
}
pubNetState = netState;
Event event = buildOnlineStateEvent(netState, OnlineStateCode.Online.getValue(), true, false, EVENT_EXPIRY);
LogUtil.ui("publish online event value = " + event.getEventValue() + " config = " + event.getConfig());
NIMClient.getService(EventSubscribeService.class).publishEvent(event);
}
// 获取网络类型
private static int getNetWorkTypeName(Context context) {
return NetworkUtil.getNetworkTypeForLink(context);
}
/**
* 多端在线时展示规则 PC > Mac > IOS/Android > Web
*/
public static OnlineState getDisplayOnlineState(Event event) {
// 获取多端的在线信息
Map<Integer, OnlineState> multiClientStates = getOnlineStateFromEvent(event);
// 取优先级最高的展示
if (multiClientStates == null || multiClientStates.isEmpty()) {
return null;
}
OnlineState result;
if (isOnline(result = multiClientStates.get(ClientType.Windows))) {
return result;
} else if (isOnline(result = multiClientStates.get(ClientType.MAC))) {
return result;
} else if (isOnline(result = multiClientStates.get(ClientType.iOS))) {
return result;
} else if (isOnline(result = multiClientStates.get(ClientType.Android))) {
return result;
} else if (isOnline(result = multiClientStates.get(ClientType.Web))) {
return result;
}
return null;
}
private static boolean isOnline(OnlineState state) {
return state != null && state.getOnlineState() != (OnlineStateCode.Offline);
}
private static boolean validNetType(OnlineState state) {
if (state == null) {
return false;
}
NetStateCode netState = state.getNetState();
return netState != null && netState != NetStateCode.Unkown;
}
/**
* 在线状态显示文案
*
* @param context
* @param state
* @param simple
* @return
*/
public static String getOnlineClientContent(Context context, OnlineState state, boolean simple) {
if (!enable) {
return null;
}
// 离线
if (!isOnline(state)) {
return context.getString(com.netease.nim.uikit.R.string.off_line);
}
// 忙碌
if (state.getOnlineState() == OnlineStateCode.Busy) {
return context.getString(com.netease.nim.uikit.R.string.on_line_busy);
}
int type = state.getOnlineClient();
String result = null;
switch (type) {
case ClientType.Windows:
result = context.getString(com.netease.nim.uikit.R.string.on_line_pc);
break;
case ClientType.MAC:
result = context.getString(com.netease.nim.uikit.R.string.on_line_mac);
break;
case ClientType.Web:
result = context.getString(com.netease.nim.uikit.R.string.on_line_web);
break;
case ClientType.Android:
result = getMobileOnlineClientString(context, state, false, simple);
break;
case ClientType.iOS:
result = getMobileOnlineClientString(context, state, true, simple);
break;
default:
break;
}
return result;
}
private static String getMobileOnlineClientString(Context context, OnlineState state, boolean ios, boolean simple) {
String result;
String client = ios ? context.getString(com.netease.nim.uikit.R.string.client_ios) : context.getString(com.netease.nim.uikit.R.string.client_aos);
if (!validNetType(state)) {
result = client + context.getString(com.netease.nim.uikit.R.string.on_line);
} else {
if (simple) {
// 简单展示
result = getDisplayNetState(state.getNetState()) + context.getString(com.netease.nim.uikit.R.string.on_line);
} else {
// 详细展示
result = client + " - " + getDisplayNetState(state.getNetState()) + context.getString(com.netease.nim.uikit.R.string.on_line);
}
}
return result;
}
private static String getDisplayNetState(NetStateCode netStateCode) {
if (netStateCode == null || netStateCode == NetStateCode.Unkown) {
return UNKNOWN;
}
if (netStateCode == NetStateCode._2G) {
return NET_TYPE_2G;
} else if (netStateCode == NetStateCode._3G) {
return NET_TYPE_3G;
} else if (netStateCode == NetStateCode._4G) {
return NET_TYPE_4G;
} else {
return NET_TYPE_WIFI;
}
}
/**
* 检查是否已经订阅过
*
* @param account
*/
public static void checkSubscribe(String account) {
if (!enable) {
return;
}
if (OnlineStateEventSubscribe.subscribeFilter(account)) {
return;
}
// 未曾订阅过
if (!OnlineStateEventCache.hasSubscribed(account)) {
List<String> accounts = new ArrayList<>(1);
accounts.add(account);
LogUtil.ui("display online state but not subscribe " + account);
OnlineStateEventSubscribe.subscribeOnlineStateEvent(accounts, OnlineStateEventSubscribe.SUBSCRIBE_EXPIRY);
}
}
public static boolean isEnable() {
return enable;
}
/**
* 允许在线状态事件,开发者开通在线状态后修改此处直接返回true
*/
private static boolean enableOnlineStateEvent() {
String packageName = DemoCache.getContext().getPackageName();
return enable = (packageName != null && packageName.equals("com.netease.nim.demo"));
}
}
@@ -0,0 +1,234 @@
package cn.shangyu.gdxzExpert.netease.event;
import android.os.Handler;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.common.framework.infra.Handlers;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.event.EventSubscribeService;
import com.netease.nimlib.sdk.event.model.EventSubscribeRequest;
import com.netease.nimlib.sdk.event.model.NimOnlineStateEvent;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import java.util.Iterator;
import java.util.List;
import cn.shangyu.gdxzExpert.netease.DemoCache;
import cn.shangyu.gdxzExpert.netease.config.preference.UserPreferences;
/**
* Created by chenkang on 2017/4/26.
*/
public class OnlineStateEventSubscribe {
// 订阅好友并同步当前在线状态的频率控制30 s,对同一账号连续2次订阅时间间隔在30s 以上
private static final long SUBS_FREQ = 30 * 1000;
private static long lastSubsTime = -1;
private static boolean initSubsFinished = true;
private static boolean waitInitSubs = false;
// 订阅有效期 1天,单位秒
public static final long SUBSCRIBE_EXPIRY = 60 * 60 * 24;
public static void initSubscribes() {
// 正在进行
if (waitInitSubs || !initSubsFinished) {
return;
}
final long timeInterval = getSubsTimeInterval();
if (timeInterval <= SUBS_FREQ) {
waitInitSubs = true;
long delay = SUBS_FREQ - timeInterval + 1000;
LogUtil.ui("time interval short than 30 and init subscribe delay " + delay);
Handler handler = Handlers.sharedHandler(DemoCache.getContext());
handler.postDelayed(new Runnable() {
@Override
public void run() {
// 延迟订阅
waitInitSubs = false;
initSubscribes();
}
}, delay);
return;
}
initSubsFinished = false;
// 重置事件、订阅关系缓存
OnlineStateEventCache.resetCache();
// 重置订阅有效期管理
SubscribeExpiryManager.reset();
// 订阅好友、最近联系人中非好友的在线状态事件
subscribeAllOnlineStateEvent();
}
private static long getSubsTimeInterval() {
if (lastSubsTime < 0) {
lastSubsTime = UserPreferences.getOnlineStateSubsTime();
}
return System.currentTimeMillis() - lastSubsTime;
}
private static void updateLastSubsTime() {
lastSubsTime = System.currentTimeMillis();
UserPreferences.setOnlineStateSubsTime(lastSubsTime);
}
/**
* 订阅好友、最近联系人的在线状态事件
*/
public static void subscribeAllOnlineStateEvent() {
final List<String> accounts = NimUIKit.getContactProvider().getUserInfoOfMyFriends();
filter(accounts);
NIMClient.getService(MsgService.class).queryRecentContacts().setCallback(new RequestCallbackWrapper<List<RecentContact>>() {
@Override
public void onResult(int code, List<RecentContact> result, Throwable exception) {
if (result != null && !result.isEmpty()) {
for (RecentContact recentContact : result) {
if (recentContact.getSessionType() == SessionTypeEnum.Team) {
continue;
}
String id = recentContact.getContactId();
if (!NimUIKit.getContactProvider().isMyFriend(id)) {
accounts.add(id);
}
}
}
initSubsFinished = true;
if (accounts.isEmpty()) {
return;
}
LogUtil.ui("subscribe friends and recentContact " + accounts);
subscribeOnlineStateEvent(accounts, SUBSCRIBE_EXPIRY);
}
});
}
/**
* 订阅指定账号的在线状态事件
*
* @param accounts 目标账号
*/
public static void subscribeOnlineStateEvent(final List<String> accounts, long expiry) {
if (waitInitSubs || !initSubsFinished || accounts == null || accounts.isEmpty()) {
return;
}
filter(accounts);
LogUtil.ui("do subscribe onlineStateEvent accounts = " + accounts);
EventSubscribeRequest eventSubscribeRequest = new EventSubscribeRequest();
eventSubscribeRequest.setEventType(NimOnlineStateEvent.EVENT_TYPE);
eventSubscribeRequest.setPublishers(accounts);
eventSubscribeRequest.setExpiry(expiry);
eventSubscribeRequest.setSyncCurrentValue(true);
OnlineStateEventCache.addSubsAccounts(accounts);
updateLastSubsTime();
NIMClient.getService(EventSubscribeService.class).subscribeEvent(eventSubscribeRequest).setCallback(new RequestCallbackWrapper<List<String>>() {
@Override
public void onResult(int code, List<String> result, Throwable exception) {
if (code == ResponseCode.RES_SUCCESS) {
// 可能网络比较慢,所以再更新一把时间
updateLastSubsTime();
SubscribeExpiryManager.subscribeSuccess();
if (result != null) {
// 部分订阅失败的账号。。。
OnlineStateEventCache.removeSubsAccounts(result);
}
} else {
OnlineStateEventCache.removeSubsAccounts(accounts);
}
}
});
}
private static void filter(final List<String> accounts) {
Iterator<String> iterator = accounts.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
if (subscribeFilter(s)) {
iterator.remove();
}
}
}
// 机器人账号不订阅
public static boolean subscribeFilter(String account) {
return NimUIKit.getRobotInfoProvider().getRobotByAccount(account) != null;
}
/**
* 取消订阅指定账号的在线状态事件
*
* @param accounts 目标账号
*/
public static void unSubscribeOnlineStateEvent(List<String> accounts) {
if (accounts == null || accounts.isEmpty()) {
return;
}
LogUtil.ui("unSubscribe OnlineStateEvent " + accounts);
OnlineStateEventCache.removeSubsAccounts(accounts);
OnlineStateEventCache.removeOnlineState(accounts);
EventSubscribeRequest eventSubscribeRequest = new EventSubscribeRequest();
eventSubscribeRequest.setEventType(NimOnlineStateEvent.EVENT_TYPE);
eventSubscribeRequest.setPublishers(accounts);
NIMClient.getService(EventSubscribeService.class).unSubscribeEvent(eventSubscribeRequest);
}
/**
* 订阅有效期管理,快到期时重新订阅
*/
private static class SubscribeExpiryManager {
private static boolean firstSubs = true;
public static void reset() {
LogUtil.ui("time task reset");
Handler handler = Handlers.sharedHandler(DemoCache.getContext());
handler.removeCallbacks(runnable);
firstSubs = true;
}
private static Runnable runnable = new Runnable() {
@Override
public void run() {
// 如果不是好友并且不在最近联系人里面,则不会续订
LogUtil.ui("time task subscribe again");
initSubscribes();
}
};
private static void startTimeTask() {
LogUtil.ui("time task start");
Handler handler = Handlers.sharedHandler(DemoCache.getContext());
handler.removeCallbacks(runnable);
handler.postDelayed(runnable, SUBSCRIBE_EXPIRY * 1000);
}
public static void subscribeSuccess() {
if (firstSubs) {
firstSubs = false;
startTimeTask();
}
}
}
}
@@ -0,0 +1,38 @@
package cn.shangyu.gdxzExpert.netease.main;
import com.netease.nimlib.sdk.msg.model.CustomNotification;
import java.util.LinkedList;
import java.util.List;
/**
* 自定义通知缓存
* <p/>
* Created by huangjun on 2015/5/29.
*/
public class CustomNotificationCache {
public static CustomNotificationCache getInstance() {
return InstanceHolder.instance;
}
private List<CustomNotification> notifications = new LinkedList<>();
public void addCustomNotification(CustomNotification notification) {
if (notification == null) {
return;
}
if (!notifications.contains(notification)) {
notifications.add(0, notification);
}
}
public List<CustomNotification> getCustomNotification() {
return notifications;
}
public static class InstanceHolder {
public final static CustomNotificationCache instance = new CustomNotificationCache();
}
}
@@ -0,0 +1,528 @@
package cn.shangyu.gdxzExpert.netease.main;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.model.main.LoginSyncDataStatusObserver;
import com.netease.nim.uikit.business.contact.selector.activity.ContactSelectActivity;
import com.netease.nim.uikit.business.team.helper.TeamHelper;
import com.netease.nim.uikit.common.ToastHelper;
import com.netease.nim.uikit.common.activity.UI;
import com.netease.nim.uikit.common.ui.dialog.DialogMaker;
import com.netease.nim.uikit.common.ui.drop.DropManager;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nim.uikit.support.permission.MPermission;
import com.netease.nim.uikit.support.permission.annotation.OnMPermissionDenied;
import com.netease.nim.uikit.support.permission.annotation.OnMPermissionGranted;
import com.netease.nim.uikit.support.permission.annotation.OnMPermissionNeverAskAgain;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.NimIntent;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.friend.FriendService;
import com.netease.nimlib.sdk.friend.constant.VerifyType;
import com.netease.nimlib.sdk.friend.model.AddFriendData;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.SystemMessageObserver;
import com.netease.nimlib.sdk.msg.SystemMessageService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.CustomNotification;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.viewpager.widget.ViewPager;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.ecdemo.ui.settings.SettingsActivity;
import cn.shangyu.gdxzExpert.netease.config.preference.Preferences;
import cn.shangyu.gdxzExpert.netease.main.adapter.MainTabPagerAdapter;
import cn.shangyu.gdxzExpert.netease.model.MainTab;
import cn.shangyu.gdxzExpert.netease.session.SessionHelper;
import cn.shangyu.gdxzExpert.netease.ui.FadeInOutPageTransformer;
import cn.shangyu.gdxzExpert.netease.ui.PagerSlidingTabStrip;
import static cn.shangyu.gdxzExpert.utils.Constant.general;
/**
* 主界面
* Created by huangjun on 2015/3/25.
*/
public class MainActivity extends UI implements ViewPager.OnPageChangeListener,
ReminderManager.UnreadNumChangedCallback {
private static final String EXTRA_APP_QUIT = "APP_QUIT";
private static final int REQUEST_CODE_NORMAL = 1;
private static final int REQUEST_CODE_ADVANCED = 2;
private static final int BASIC_PERMISSION_REQUEST_CODE = 100;
private static final String[] BASIC_PERMISSIONS = new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION};
private PagerSlidingTabStrip tabs;
private ViewPager pager;
private int scrollState;
private MainTabPagerAdapter adapter;
private boolean isFirstIn;
private Observer<Integer> sysMsgUnreadCountChangedObserver = (Observer<Integer>) unreadCount -> {
SystemMessageUnreadManager.getInstance().setSysMsgUnreadCount(unreadCount);
ReminderManager.getInstance().updateContactUnreadNum(unreadCount);
};
public static void start(Context context) {
start(context, null);
}
public static void start(Context context, Intent extras) {
Intent intent = new Intent();
intent.setClass(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
if (extras != null) {
intent.putExtras(extras);
}
context.startActivity(intent);
}
// 注销
public static void logout(Context context, boolean quit) {
Intent extra = new Intent();
extra.putExtra(EXTRA_APP_QUIT, quit);
start(context, extra);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// setToolBar(R.id.toolbar, R.string.app_name, R.drawable.actionbar_dark_logo);
setTitle(R.string.app_name);
isFirstIn = true;
//不保留后台活动,从厂商推送进聊天页面,会无法退出聊天页面
if (savedInstanceState == null && parseIntent()) {
return;
}
init();
addFriends();
}
private void init() {
observerSyncDataComplete();
findViews();
setupPager();
setupTabs();
registerMsgUnreadInfoObserver(true);
registerSystemMessageObservers(true);
registerCustomMessageObservers(true);
requestSystemMessageUnreadCount();
initUnreadCover();
requestBasicPermission();
}
private void addFriends()
{
NIMClient.getService(FriendService.class).addFriend(new AddFriendData("gdxz_ad01", VerifyType.DIRECT_ADD, "hello"));
}
private boolean parseIntent() {
Intent intent = getIntent();
if (intent.hasExtra(EXTRA_APP_QUIT)) {
intent.removeExtra(EXTRA_APP_QUIT);
onLogout();
return true;
}
if (intent.hasExtra(NimIntent.EXTRA_NOTIFY_CONTENT)) {
IMMessage message = (IMMessage) intent.getSerializableExtra(
NimIntent.EXTRA_NOTIFY_CONTENT);
intent.removeExtra(NimIntent.EXTRA_NOTIFY_CONTENT);
switch (message.getSessionType()) {
case P2P:
SessionHelper.startP2PSession(this, message.getSessionId(),general,"");
break;
case Team:
SessionHelper.startTeamSession(this, message.getSessionId());
break;
}
return true;
}
// if (intent.hasExtra(AVChatActivity.INTENT_ACTION_AVCHAT) &&
// AVChatProfile.getInstance().isAVChatting()) {
// intent.removeExtra(AVChatActivity.INTENT_ACTION_AVCHAT);
// Intent localIntent = new Intent();
// localIntent.setClass(this, AVChatActivity.class);
// startActivity(localIntent);
// return true;
// }
// String account = intent.getStringExtra(AVChatExtras.EXTRA_ACCOUNT);
// if (intent.hasExtra(AVChatExtras.EXTRA_FROM_NOTIFICATION) && !TextUtils.isEmpty(account)) {
// intent.removeExtra(AVChatExtras.EXTRA_FROM_NOTIFICATION);
// SessionHelper.startP2PSession(this, account);
// return true;
// }
return false;
}
private void observerSyncDataComplete() {
boolean syncCompleted = LoginSyncDataStatusObserver.getInstance()
.observeSyncDataCompletedEvent(
(Observer<Void>) v -> DialogMaker
.dismissProgressDialog());
//如果数据没有同步完成,弹个进度Dialog
if (!syncCompleted) {
DialogMaker.showProgressDialog(MainActivity.this, getString(com.netease.nim.uikit.R.string.prepare_data))
.setCanceledOnTouchOutside(false);
}
}
private void findViews() {
tabs = findView(R.id.tabs);
pager = findView(R.id.main_tab_pager);
}
private void setupPager() {
adapter = new MainTabPagerAdapter(getSupportFragmentManager(), this, pager);
pager.setOffscreenPageLimit(adapter.getCacheCount());
pager.setPageTransformer(true, new FadeInOutPageTransformer());
pager.setAdapter(adapter);
pager.setOnPageChangeListener(this);
}
private void setupTabs() {
tabs.setOnCustomTabListener(new PagerSlidingTabStrip.OnCustomTabListener() {
@Override
public int getTabLayoutResId(int position) {
return R.layout.tab_layout_main;
}
@Override
public boolean screenAdaptation() {
return true;
}
});
tabs.setViewPager(pager);
tabs.setOnTabClickListener(adapter);
tabs.setOnTabDoubleTapListener(adapter);
}
/**
* 注册未读消息数量观察者
*/
private void registerMsgUnreadInfoObserver(boolean register) {
if (register) {
ReminderManager.getInstance().registerUnreadNumChangedCallback(this);
} else {
ReminderManager.getInstance().unregisterUnreadNumChangedCallback(this);
}
}
/**
* 注册/注销系统消息未读数变化
*/
private void registerSystemMessageObservers(boolean register) {
NIMClient.getService(SystemMessageObserver.class).observeUnreadCountChange(
sysMsgUnreadCountChangedObserver, register);
}
// sample
Observer<CustomNotification> customNotificationObserver = (Observer<CustomNotification>) notification -> {
// 处理自定义通知消息
LogUtil.i("demo", "receive custom notification: " + notification.getContent() + " from :" +
notification.getSessionId() + "/" + notification.getSessionType() +
"unread=" + (notification.getConfig() == null ? "" : notification.getConfig().enableUnreadCount + " " + "push=" +
notification.getConfig().enablePush + " nick=" +
notification.getConfig().enablePushNick));
try {
JSONObject obj = JSONObject.parseObject(notification.getContent());
if (obj != null && obj.getIntValue("id") == 2) {
// 加入缓存中
CustomNotificationCache.getInstance().addCustomNotification(notification);
// Toast
String content = obj.getString("content");
String tip = String.format("自定义消息[%s]:%s", notification.getFromAccount(), content);
ToastHelper.showToast(MainActivity.this, tip);
}
} catch (JSONException e) {
LogUtil.e("demo", e.getMessage());
}
};
private void registerCustomMessageObservers(boolean register) {
NIMClient.getService(MsgServiceObserve.class).observeCustomNotification(
customNotificationObserver, register);
}
/**
* 查询系统消息未读数
*/
private void requestSystemMessageUnreadCount() {
int unread = NIMClient.getService(SystemMessageService.class)
.querySystemMessageUnreadCountBlock();
SystemMessageUnreadManager.getInstance().setSysMsgUnreadCount(unread);
ReminderManager.getInstance().updateContactUnreadNum(unread);
}
//初始化未读红点动画
private void initUnreadCover() {
DropManager.getInstance().init(this, findView(R.id.unread_cover), (id, explosive) -> {
if (id == null || !explosive) {
return;
}
if (id instanceof RecentContact) {
RecentContact r = (RecentContact) id;
NIMClient.getService(MsgService.class).clearUnreadCount(r.getContactId(),
r.getSessionType());
return;
}
if (id instanceof String) {
if (((String) id).contentEquals("0")) {
NIMClient.getService(MsgService.class).clearAllUnreadCount();
} else if (((String) id).contentEquals("1")) {
NIMClient.getService(SystemMessageService.class)
.resetSystemMessageUnreadCount();
}
}
});
}
private void requestBasicPermission() {
MPermission.printMPermissionResult(true, this, BASIC_PERMISSIONS);
MPermission.with(MainActivity.this).setRequestCode(BASIC_PERMISSION_REQUEST_CODE)
.permissions(BASIC_PERMISSIONS).request();
}
private void onLogout() {
Preferences.saveUserToken("");
// 清理缓存&注销监听
// LogoutHelper.logout();
// 启动登录
// LoginActivity.start(this);
finish();
}
private void selectPage() {
if (scrollState == ViewPager.SCROLL_STATE_IDLE) {
adapter.onPageSelected(pager.getCurrentItem());
}
}
/**
* 设置最近联系人的消息为已读
* <p>
* account, 聊天对象帐号,或者以下两个值:
* {@link MsgService#MSG_CHATTING_ACCOUNT_ALL} 目前没有与任何人对话,但能看到消息提醒(比如在消息列表界面),不需要在状态栏做消息通知
* {@link MsgService#MSG_CHATTING_ACCOUNT_NONE} 目前没有与任何人对话,需要状态栏消息通知
*/
private void enableMsgNotification(boolean enable) {
boolean msg = (pager.getCurrentItem() != MainTab.RECENT_CONTACTS.tabIndex);
if (enable | msg) {
NIMClient.getService(MsgService.class).setChattingAccount(
MsgService.MSG_CHATTING_ACCOUNT_NONE, SessionTypeEnum.None);
} else {
NIMClient.getService(MsgService.class).setChattingAccount(
MsgService.MSG_CHATTING_ACCOUNT_ALL, SessionTypeEnum.None);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(com.netease.nim.uikit.R.menu.main_activity_menu, menu);
super.onCreateOptionsMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case com.netease.nim.uikit.R.id.about:
startActivity(new Intent(MainActivity.this, SettingsActivity.class));
break;
case com.netease.nim.uikit.R.id.view_cloud_session:
// RecentSessionActivity.start(this);
break;
case com.netease.nim.uikit.R.id.create_normal_team:
ContactSelectActivity.Option option = TeamHelper.getCreateContactSelectOption(null,
50);
NimUIKit.startContactSelector(MainActivity.this, option, REQUEST_CODE_NORMAL);
break;
case com.netease.nim.uikit.R.id.create_regular_team:
ContactSelectActivity.Option advancedOption = TeamHelper
.getCreateContactSelectOption(null, 50);
NimUIKit.startContactSelector(MainActivity.this, advancedOption,
REQUEST_CODE_ADVANCED);
break;
case com.netease.nim.uikit.R.id.search_advanced_team:
// AdvancedTeamSearchActivity.start(MainActivity.this);
break;
case R.id.add_buddy:
// AddFriendActivity.start(MainActivity.this);
break;
case com.netease.nim.uikit.R.id.search_btn:
// GlobalSearchActivity.start(MainActivity.this);
break;
case com.netease.nim.uikit.R.id.enter_ysf:
// Unicorn.openServiceActivity(this, "七鱼测试", null);
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
parseIntent();
}
@Override
public void onResume() {
super.onResume();
// 第一次 , 三方通知唤起进会话页面之类的,不会走初始化过程
boolean temp = isFirstIn;
isFirstIn = false;
if (pager == null && temp) {
return;
}
//如果不是第一次进 , eg: 其他页面back
if (pager == null) {
init();
}
enableMsgNotification(false);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.clear();
}
@Override
public void onPause() {
super.onPause();
if (pager == null) {
return;
}
enableMsgNotification(true);
}
@Override
public void onDestroy() {
registerMsgUnreadInfoObserver(false);
registerSystemMessageObservers(false);
registerCustomMessageObservers(false);
DropManager.getInstance().destroy();
super.onDestroy();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_CODE_NORMAL) {
final ArrayList<String> selected = data.getStringArrayListExtra(
ContactSelectActivity.RESULT_DATA);
if (selected != null && !selected.isEmpty()) {
// TeamCreateHelper.createNormalTeam(MainActivity.this, selected, false, null);
} else {
ToastHelper.showToast(MainActivity.this, "请选择至少一个联系人!");
}
} else if (requestCode == REQUEST_CODE_ADVANCED) {
final ArrayList<String> selected = data.getStringArrayListExtra(
ContactSelectActivity.RESULT_DATA);
// TeamCreateHelper.createAdvancedTeam(MainActivity.this, selected);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
tabs.onPageScrolled(position, positionOffset, positionOffsetPixels);
adapter.onPageScrolled(position);
}
@Override
public void onPageSelected(int position) {
tabs.onPageSelected(position);
selectPage();
enableMsgNotification(false);
}
@Override
public void onPageScrollStateChanged(int state) {
tabs.onPageScrollStateChanged(state);
scrollState = state;
selectPage();
}
//未读消息数量观察者实现
@Override
public void onUnreadNumChanged(ReminderItem item) {
MainTab tab = MainTab.fromReminderId(item.getId());
if (tab != null) {
tabs.updateTab(tab.tabIndex, item);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
MPermission.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
}
@OnMPermissionGranted(BASIC_PERMISSION_REQUEST_CODE)
public void onBasicPermissionSuccess() {
try {
ToastHelper.showToast(this, "授权成功");
} catch (Exception e) {
e.printStackTrace();
}
MPermission.printMPermissionResult(false, this, BASIC_PERMISSIONS);
}
@OnMPermissionDenied(BASIC_PERMISSION_REQUEST_CODE)
@OnMPermissionNeverAskAgain(BASIC_PERMISSION_REQUEST_CODE)
public void onBasicPermissionFailed() {
try {
ToastHelper.showToast(this, "未全部授权,部分功能可能无法正常运行!");
} catch (Exception e) {
e.printStackTrace();
}
MPermission.printMPermissionResult(false, this, BASIC_PERMISSIONS);
}
@Override
protected boolean displayHomeAsUpEnabled() {
return false;
}
}
@@ -0,0 +1,7 @@
package cn.shangyu.gdxzExpert.netease.main;
public class ReminderId {
final static public int INVALID = -1;
final static public int SESSION = 0;
final static public int CONTACT = 1;
}
@@ -0,0 +1,53 @@
package cn.shangyu.gdxzExpert.netease.main;
import java.io.Serializable;
public class ReminderItem implements Serializable {
private static final long serialVersionUID = -2101649256143239157L;
protected final int id;
private int unread;
private boolean indicator;
public ReminderItem(int id) {
this.id = id;
this.unread = 0;
}
public int getId() {
return id;
}
public int unread() {
return unread;
}
public boolean indicator() {
return unread <= 0 && indicator;
}
public int getUnread() {
return unread;
}
public void setUnread(int unread) {
this.unread = unread;
}
public void setIndicator(boolean indicator) {
this.indicator = indicator;
}
/*package*/ ReminderItem copy() {
ReminderItem item = new ReminderItem(id);
copyData(item);
return item;
}
protected void copyData(ReminderItem item) {
item.unread = this.unread;
item.indicator = this.indicator;
}
}
@@ -0,0 +1,98 @@
package cn.shangyu.gdxzExpert.netease.main;
import android.util.SparseArray;
import java.util.ArrayList;
import java.util.List;
/**
* TAB红点提醒管理器
* Created by huangjun on 2015/3/18.
*/
public class ReminderManager {
// callback
public interface UnreadNumChangedCallback {
void onUnreadNumChanged(ReminderItem item);
}
// singleton
private static ReminderManager instance;
public static synchronized ReminderManager getInstance() {
if (instance == null) {
instance = new ReminderManager();
}
return instance;
}
// observers
private SparseArray<ReminderItem> items = new SparseArray<>();
private List<UnreadNumChangedCallback> unreadNumChangedCallbacks = new ArrayList<>();
private ReminderManager() {
populate(items);
}
// interface
public final void updateSessionUnreadNum(int unreadNum) {
updateUnreadMessageNum(unreadNum, false, ReminderId.SESSION);
}
public final void updateSessionDeltaUnreadNum(int delta) {
updateUnreadMessageNum(delta, true, ReminderId.SESSION);
}
public final void updateContactUnreadNum(int unreadNum) {
updateUnreadMessageNum(unreadNum, false, ReminderId.CONTACT);
}
public void registerUnreadNumChangedCallback(UnreadNumChangedCallback cb) {
if (unreadNumChangedCallbacks.contains(cb)) {
return;
}
unreadNumChangedCallbacks.add(cb);
}
public void unregisterUnreadNumChangedCallback(UnreadNumChangedCallback cb) {
if (!unreadNumChangedCallbacks.contains(cb)) {
return;
}
unreadNumChangedCallbacks.remove(cb);
}
// inner
private final void populate(SparseArray<ReminderItem> items) {
items.put(ReminderId.SESSION, new ReminderItem(ReminderId.SESSION));
items.put(ReminderId.CONTACT, new ReminderItem(ReminderId.CONTACT));
}
private final void updateUnreadMessageNum(int unreadNum, boolean delta, int reminderId) {
ReminderItem item = items.get(reminderId);
if (item == null) {
return;
}
int num = item.getUnread();
// 增量
if (delta) {
num = num + unreadNum;
if (num < 0) {
num = 0;
}
} else {
num = unreadNum;
}
item.setUnread(num);
item.setIndicator(false);
for (UnreadNumChangedCallback cb : unreadNumChangedCallbacks) {
cb.onUnreadNumChanged(item);
}
}
}
@@ -0,0 +1,12 @@
package cn.shangyu.gdxzExpert.netease.main;
public class ReminderSettings {
/**
* 最大显示未读数
*/
public static final int MAX_UNREAD_SHOW_NUMBER = 99;
public static int unreadMessageShowRule(int unread) {
return Math.min(MAX_UNREAD_SHOW_NUMBER, unread);
}
}
@@ -0,0 +1,23 @@
package cn.shangyu.gdxzExpert.netease.main;
/**
* Created by huangjun on 2015/8/20.
*/
public class SystemMessageUnreadManager {
private static SystemMessageUnreadManager instance = new SystemMessageUnreadManager();
public static SystemMessageUnreadManager getInstance() {
return instance;
}
private int sysMsgUnreadCount = 0;
public int getSysMsgUnreadCount() {
return sysMsgUnreadCount;
}
public synchronized void setSysMsgUnreadCount(int unreadCount) {
this.sysMsgUnreadCount = unreadCount;
}
}
@@ -0,0 +1,62 @@
package cn.shangyu.gdxzExpert.netease.main.adapter;
import android.content.Context;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager.widget.ViewPager;
import java.util.List;
import cn.shangyu.gdxzExpert.netease.main.fragment.MainTabFragment;
import cn.shangyu.gdxzExpert.netease.model.MainTab;
import cn.shangyu.gdxzExpert.netease.ui.SlidingTabPagerAdapter;
public class MainTabPagerAdapter extends SlidingTabPagerAdapter {
@Override
public int getCacheCount() {
return MainTab.values().length;
}
public MainTabPagerAdapter(FragmentManager fm, Context context, ViewPager pager) {
super(fm, MainTab.values().length, context.getApplicationContext(), pager);
for (MainTab tab : MainTab.values()) {
try {
MainTabFragment fragment = null;
List<Fragment> fs = fm.getFragments();
if (fs != null) {
for (Fragment f : fs) {
if (f.getClass() == tab.clazz) {
fragment = (MainTabFragment) f;
break;
}
}
}
if (fragment == null) {
fragment = tab.clazz.newInstance();
}
fragment.setState(this);
fragment.attachTabData(tab);
fragments[tab.tabIndex] = fragment;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
@Override
public int getCount() {
return MainTab.values().length;
}
@Override
public CharSequence getPageTitle(int position) {
MainTab tab = MainTab.fromTabIndex(position);
int resId = tab != null ? tab.resId : 0;
return resId != 0 ? context.getText(resId) : "";
}
}
@@ -0,0 +1,31 @@
package cn.shangyu.gdxzExpert.netease.main.fragment;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.model.MainTab;
/**
* 聊天室主TAB页
* Created by huangjun on 2015/12/11.
*/
public class ChatRoomListFragment extends MainTabFragment {
private ChatRoomListFragment fragment;
public ChatRoomListFragment() {
setContainerId(MainTab.CHAT_ROOM.fragmentId);
}
@Override
protected void onInit() {
// 采用静态集成,这里不需要做什么了
fragment = (ChatRoomListFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.chat_rooms_fragment);
}
@Override
public void onCurrent() {
super.onCurrent();
if (fragment != null) {
fragment.onCurrent();
}
}
}
@@ -0,0 +1,88 @@
package cn.shangyu.gdxzExpert.netease.main.fragment;
import android.os.Bundle;
import com.netease.nim.uikit.api.model.contact.ContactsCustomization;
import com.netease.nim.uikit.business.contact.ContactsFragment;
import com.netease.nim.uikit.business.contact.core.item.AbsContactItem;
import com.netease.nim.uikit.business.contact.core.viewholder.AbsContactViewHolder;
import com.netease.nim.uikit.common.activity.UI;
import java.util.List;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.main.viewholder.FuncViewHolder;
import cn.shangyu.gdxzExpert.netease.model.MainTab;
/**
* 集成通讯录列表
* <p/>
* Created by huangjun on 2015/9/7.
*/
public class ContactListFragment extends MainTabFragment {
private ContactsFragment fragment;
public ContactListFragment() {
setContainerId(MainTab.CONTACT.fragmentId);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
onCurrent(); // 触发onInit,提前加载
}
@Override
protected void onInit() {
// addContactFragment(); // 集成通讯录页面
}
// 将通讯录列表fragment动态集成进来。 开发者也可以使用在xml中配置的方式静态集成。
private void addContactFragment() {
fragment = new ContactsFragment();
fragment.setContainerId(R.id.contact_fragment);
UI activity = (UI) getActivity();
// 如果是activity从堆栈恢复,FM中已经存在恢复而来的fragment,此时会使用恢复来的,而new出来这个会被丢弃掉
fragment = (ContactsFragment) activity.addFragment(fragment);
// 功能项定制
fragment.setContactsCustomization(new ContactsCustomization() {
@Override
public Class<? extends AbsContactViewHolder<? extends AbsContactItem>> onGetFuncViewHolderClass() {
return FuncViewHolder.class;
}
@Override
public List<AbsContactItem> onGetFuncItems() {
return FuncViewHolder.FuncItem.provide();
}
@Override
public void onFuncItemClick(AbsContactItem item) {
FuncViewHolder.FuncItem.handle(getActivity(), item);
}
});
}
@Override
public void onCurrentTabClicked() {
// 点击切换到当前TAB
if (fragment != null) {
fragment.scrollToTop();
}
}
@Override
public void onDestroy() {
super.onDestroy();
FuncViewHolder.unRegisterUnreadNumChangedCallback();
}
}
@@ -0,0 +1,58 @@
package cn.shangyu.gdxzExpert.netease.main.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.netease.nim.uikit.common.fragment.TabFragment;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.model.MainTab;
public abstract class MainTabFragment extends TabFragment {
private boolean loaded = false;
private MainTab tabData;
protected abstract void onInit();
protected boolean inited() {
return loaded;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.main_tab_fragment_container, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
public void attachTabData(MainTab tabData) {
this.tabData = tabData;
}
@Override
public void onCurrent() {
super.onCurrent();
if (!loaded && loadRealLayout()) {
loaded = true;
onInit();
}
}
private boolean loadRealLayout() {
ViewGroup root = (ViewGroup) getView();
if (root != null) {
root.removeAllViewsInLayout();
View.inflate(root.getContext(), R.layout.session_list, root);
}
return root != null;
}
}
@@ -0,0 +1,286 @@
package cn.shangyu.gdxzExpert.netease.main.fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.netease.nim.uikit.business.recent.RecentContactsCallback;
import com.netease.nim.uikit.common.ToastHelper;
import com.netease.nim.uikit.common.activity.UI;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nim.uikit.common.util.log.sdk.wrapper.NimLog;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.StatusCode;
import com.netease.nimlib.sdk.auth.AuthService;
import com.netease.nimlib.sdk.auth.AuthServiceObserver;
import com.netease.nimlib.sdk.auth.ClientType;
import com.netease.nimlib.sdk.auth.OnlineClient;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.config.preference.Preferences;
import cn.shangyu.gdxzExpert.netease.main.ReminderManager;
import cn.shangyu.gdxzExpert.netease.model.MainTab;
import cn.shangyu.gdxzExpert.netease.ptop.RecentContactsFragment;
import cn.shangyu.gdxzExpert.netease.session.SessionHelper;
import cn.shangyu.gdxzExpert.netease.session.extension.GuessAttachment;
import cn.shangyu.gdxzExpert.netease.session.extension.MultiRetweetAttachment;
import cn.shangyu.gdxzExpert.netease.session.extension.RedPacketAttachment;
import cn.shangyu.gdxzExpert.netease.session.extension.RedPacketOpenedAttachment;
import cn.shangyu.gdxzExpert.netease.session.extension.TeachAttachment;
import static cn.shangyu.gdxzExpert.utils.Constant.general;
/**
* Created by zhoujianghua on 2015/8/17.
*/
public class SessionListFragment extends MainTabFragment {
private static final String TAG = SessionListFragment.class.getSimpleName();
private View notifyBar;
private TextView notifyBarText;
// 同时在线的其他端的信息
private List<OnlineClient> onlineClients;
private View multiportBar;
private RecentContactsFragment fragment;
public SessionListFragment() {
this.setContainerId(MainTab.RECENT_CONTACTS.fragmentId);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
onCurrent();
}
@Override
public void onDestroy() {
registerObservers(false);
super.onDestroy();
}
@Override
protected void onInit() {
findViews();
registerObservers(true);
addRecentContactsFragment();
}
private void registerObservers(boolean register) {
NIMClient.getService(AuthServiceObserver.class).observeOtherClients(clientsObserver, register);
// NIMClient.getService(AuthServiceObserver.class).observeOnlineStatus(userStatusObserver, register);
}
private void findViews() {
notifyBar = getView().findViewById(R.id.status_notify_bar);
notifyBarText = getView().findViewById(R.id.status_desc_label);
notifyBar.setVisibility(View.GONE);
multiportBar = getView().findViewById(R.id.multiport_notify_bar);
multiportBar.setVisibility(View.GONE);
multiportBar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// MultiportActivity.startActivity(getActivity(), onlineClients);
}
});
}
/**
* 用户状态变化
*/
Observer<StatusCode> userStatusObserver = new Observer<StatusCode>() {
@Override
public void onEvent(StatusCode code) {
if (code.wontAutoLogin()) {
kickOut(code);
NimLog.i(TAG, "kick out desc: " + code.getDesc());
} else {
if (code == StatusCode.NET_BROKEN) {
notifyBar.setVisibility(View.VISIBLE);
notifyBarText.setText(R.string.net_broken);
} else if (code == StatusCode.UNLOGIN) {
notifyBar.setVisibility(View.VISIBLE);
// notifyBarText.setText(R.string.nim_status_unlogin);
} else if (code == StatusCode.CONNECTING) {
notifyBar.setVisibility(View.VISIBLE);
// notifyBarText.setText(R.string.nim_status_connecting);
} else if (code == StatusCode.LOGINING) {
notifyBar.setVisibility(View.VISIBLE);
// notifyBarText.setText(R.string.nim_status_logining);
} else {
notifyBar.setVisibility(View.GONE);
}
}
}
};
Observer<List<OnlineClient>> clientsObserver = new Observer<List<OnlineClient>>() {
@Override
public void onEvent(List<OnlineClient> onlineClients) {
SessionListFragment.this.onlineClients = onlineClients;
if (onlineClients == null || onlineClients.size() == 0) {
multiportBar.setVisibility(View.GONE);
} else {
multiportBar.setVisibility(View.VISIBLE);
TextView status = multiportBar.findViewById(R.id.multiport_desc_label);
OnlineClient client = onlineClients.get(0);
for (OnlineClient temp : onlineClients) {
Log.d(TAG, "type : " + temp.getClientType() + " , customTag : " + temp.getCustomTag());
}
switch (client.getClientType()) {
case ClientType.Windows:
case ClientType.MAC:
// status.setText(getString(R.string.multiport_logging) + getString(R.string.computer_version));
break;
case ClientType.Web:
// status.setText(getString(R.string.multiport_logging) + getString(R.string.web_version));
break;
case ClientType.iOS:
case ClientType.Android:
// status.setText(getString(R.string.multiport_logging) + getString(R.string.mobile_version));
break;
default:
multiportBar.setVisibility(View.GONE);
break;
}
}
}
};
private void kickOut(StatusCode code) {
Preferences.saveUserToken("");
if (code == StatusCode.PWD_ERROR) {
LogUtil.e("Auth", "user password error");
// ToastHelper.showToast(getActivity(), R.string.login_failed);
} else {
LogUtil.i("Auth", "Kicked!");
}
if (code == StatusCode.DATA_UPGRADE) {
// onLogout(getString(R.string.kickout_encrypt_database));
} else {
onLogout("");
}
}
// 注销
private void onLogout(String desc) {
// 清理缓存&注销监听&清除状态
// LogoutHelper.logout();
// LoginActivity.start(getActivity(), true, desc);
NIMClient.getService(AuthService.class).logout();
getActivity().finish();
}
// 将最近联系人列表fragment动态集成进来。 开发者也可以使用在xml中配置的方式静态集成。
private void addRecentContactsFragment() {
fragment = new RecentContactsFragment();
fragment.setContainerId(R.id.messages_fragment);
final UI activity = (UI) getActivity();
// 如果是activity从堆栈恢复,FM中已经存在恢复而来的fragment,此时会使用恢复来的,而new出来这个会被丢弃掉
fragment = (RecentContactsFragment) activity.addFragment(fragment);
fragment.setCallback(new RecentContactsCallback() {
@Override
public void onRecentContactsLoaded() {
// 最近联系人列表加载完毕
}
@Override
public void onUnreadCountChange(int unreadCount) {
ReminderManager.getInstance().updateSessionUnreadNum(unreadCount);
}
@Override
public void onItemClick(RecentContact recent,int p) {
// 回调函数,以供打开会话窗口时传入定制化参数,或者做其他动作
switch (recent.getSessionType()) {
case P2P:
SessionHelper.startP2PSession(getActivity(), recent.getContactId(),general,"");
break;
case Team:
SessionHelper.startTeamSession(getActivity(), recent.getContactId());
break;
case SUPER_TEAM:
ToastHelper.showToast(getActivity(), "超大群开发者按需实现");
break;
case Ysf:
// Unicorn.openServiceActivity(getContext(), "七鱼测试", null);
break;
default:
break;
}
}
@Override
public String getDigestOfAttachment(RecentContact recentContact, MsgAttachment attachment) {
// 设置自定义消息的摘要消息,展示在最近联系人列表的消息缩略栏上
// 当然,你也可以自定义一些内建消息的缩略语,例如图片,语音,音视频会话等,自定义的缩略语会被优先使用。
if (attachment instanceof GuessAttachment) {
GuessAttachment guess = (GuessAttachment) attachment;
return guess.getValue().getDesc();
}
// else if (attachment instanceof RTSAttachment) {
// return "[白板]";
// } else if (attachment instanceof StickerAttachment) {
// return "[贴图]";
// } else if (attachment instanceof SnapChatAttachment) {
// return "[阅后即焚]";
// }
else if (attachment instanceof RedPacketAttachment) {
return "[红包]";
} else if (attachment instanceof RedPacketOpenedAttachment) {
return ((RedPacketOpenedAttachment) attachment).getDesc(recentContact.getSessionType(), recentContact.getContactId());
} else if (attachment instanceof MultiRetweetAttachment){
return "[聊天记录]";
} else if (attachment instanceof TeachAttachment){
return "[图文患教]";
}
return null;
}
@Override
public String getDigestOfTipMsg(RecentContact recent) {
String msgId = recent.getRecentMessageId();
List<String> uuids = new ArrayList<>(1);
uuids.add(msgId);
List<IMMessage> msgs = NIMClient.getService(MsgService.class).queryMessageListByUuidBlock(uuids);
if (msgs != null && !msgs.isEmpty()) {
IMMessage msg = msgs.get(0);
Map<String, Object> content = msg.getRemoteExtension();
if (content != null && !content.isEmpty()) {
return (String) content.get("content");
}
}
return null;
}
});
}
}
@@ -0,0 +1,410 @@
package cn.shangyu.gdxzExpert.netease.main.fragment;
import static cn.shangyu.gdxzExpert.ecdemo.common.utils.CommomUtil.simpleDateFormat;
import static cn.shangyu.gdxzExpert.netease.ptop.P2PMessageActivity.startfor;
import static cn.shangyu.gdxzExpert.utils.Constant.general;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.netease.nim.uikit.business.recent.RecentContactsCallback;
import com.netease.nim.uikit.common.ToastHelper;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nim.uikit.common.util.log.sdk.wrapper.NimLog;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.StatusCode;
import com.netease.nimlib.sdk.auth.AuthService;
import com.netease.nimlib.sdk.auth.AuthServiceObserver;
import com.netease.nimlib.sdk.auth.ClientType;
import com.netease.nimlib.sdk.auth.OnlineClient;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import java.io.InvalidClassException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.activity.LoginNewActivity;
import cn.shangyu.gdxzExpert.base.BaseActivity;
import cn.shangyu.gdxzExpert.base.BaseFragment;
import cn.shangyu.gdxzExpert.ecdemo.common.ECPreferenceSettings;
import cn.shangyu.gdxzExpert.ecdemo.common.ECPreferences;
import cn.shangyu.gdxzExpert.ecdemo.view.NetWarnBannerView;
import cn.shangyu.gdxzExpert.netease.config.preference.Preferences;
import cn.shangyu.gdxzExpert.netease.main.ReminderManager;
import cn.shangyu.gdxzExpert.netease.ptop.RecentContactsFragment;
import cn.shangyu.gdxzExpert.netease.session.SessionHelper;
import cn.shangyu.gdxzExpert.netease.session.extension.GuessAttachment;
import cn.shangyu.gdxzExpert.netease.session.extension.MultiRetweetAttachment;
import cn.shangyu.gdxzExpert.netease.session.extension.RedPacketAttachment;
import cn.shangyu.gdxzExpert.netease.session.extension.RedPacketOpenedAttachment;
import cn.shangyu.gdxzExpert.netease.session.extension.TeachAttachment;
import cn.shangyu.gdxzExpert.utils.DataCleanManager;
import cn.shangyu.gdxzExpert.utils.UIUtils;
import cn.shangyu.gdxzExpert.widget.ECAlertDialog;
import cn.shangyu.gdxzExpert.widget.LoadingPage;
/**
* Created by zhoujianghua on 2015/8/17.
*/
public class SessionListFragmentNew extends BaseFragment {
private static final String TAG = SessionListFragmentNew.class.getSimpleName();
// private View notifyBar;
private NetWarnBannerView mBannerView;
// private TextView notifyBarText;
// 同时在线的其他端的信息
private List<OnlineClient> onlineClients;
// private View multiportBar;
private RecentContactsFragment fragment;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = UIUtils.inflate(R.layout.session_list);
// notifyBar = view.findViewById(R.id.status_notify_bar);
// notifyBarText = view.findViewById(R.id.status_desc_label);
// notifyBar.setVisibility(View.GONE);
mBannerView=view.findViewById(R.id.network_banner);
// multiportBar = view.findViewById(R.id.multiport_notify_bar);
// multiportBar.setVisibility(View.GONE);
// multiportBar.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
//// MultiportActivity.startActivity(getActivity(), onlineClients);
// }
// });
onInit();
return view;
}
@Override
public void onResume() {
super.onResume();
needreportPage("患者消息");
}
@Override
public void onDestroy() {
registerObservers(false);
super.onDestroy();
}
protected void onInit() {
registerObservers(true);
addRecentContactsFragment();
}
private void registerObservers(boolean register) {
NIMClient.getService(AuthServiceObserver.class).observeOtherClients(clientsObserver, register);
NIMClient.getService(AuthServiceObserver.class).observeOnlineStatus(userStatusObserver, register);
}
private void showlogout()
{
Date date = new Date(System.currentTimeMillis());
String phone="ios";
switch(NIMClient.getService(AuthService.class).getKickedClientType())
{
case 1:
phone="android";
break;
case 2:
phone="ios";
break;
case 16:
phone="web";
break;
default:
phone="unknow";
break;
}
ECAlertDialog buildAlert = ECAlertDialog.buildAlert(getActivity(),
getString(R.string.nim_kick_out)+
simpleDateFormat.format(date)+getString(R.string.nim_kick_out1)+
phone+getString(R.string.nim_kick_out2)
, getString(R.string.dialog_btn_confim),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(getActivity(), LoginNewActivity.class));
getActivity().finish();
}
});
buildAlert.setTitle("异地登陆");
buildAlert.setCanceledOnTouchOutside(false);
buildAlert.setCancelable(false);
buildAlert.show();
}
/**
* 用户状态变化
*/
Observer<StatusCode> userStatusObserver = new Observer<StatusCode>() {
@Override
public void onEvent(StatusCode code) {
if (code.wontAutoLogin()) {
// LogoutHelper.logout();
// showlogout();
// startActivity(new Intent(getActivity(), LoginActivity.class));
// getActivity().finish();
// handleLogout();
// kickOut(code);
// restartAPP();
mBannerView.setVisibility(View.GONE);
NimLog.i(TAG, "kick out desc: " + code.getDesc());
} else {
if (code == StatusCode.NET_BROKEN) {
// notifyBar.setVisibility(View.VISIBLE);
// notifyBarText.setText(R.string.net_broken);
mBannerView.setVisibility(View.VISIBLE);
mBannerView.setNetWarnText(getString(R.string.nim_status_notlog));
// ToastUtil.showMessage(R.string.nim_status_notlog);
} else if (code == StatusCode.UNLOGIN) {
// notifyBar.setVisibility(View.VISIBLE);
// notifyBarText.setText(R.string.nim_status_unlogin);
mBannerView.setVisibility(View.VISIBLE);
mBannerView.setNetWarnText(getString(R.string.nim_status_notlog));
// ToastUtil.showMessage(R.string.nim_status_notlog);
} else if (code == StatusCode.CONNECTING) {
mBannerView.setVisibility(View.GONE);
// notifyBar.setVisibility(View.VISIBLE);
// notifyBarText.setText(R.string.nim_status_connecting);
} else if (code == StatusCode.LOGINING) {
mBannerView.setVisibility(View.GONE);
// notifyBar.setVisibility(View.VISIBLE);
// notifyBarText.setText(R.string.nim_status_logining);
} else {
mBannerView.setVisibility(View.GONE);
// notifyBar.setVisibility(View.GONE);
}
}
}
};
Observer<List<OnlineClient>> clientsObserver = new Observer<List<OnlineClient>>() {
@Override
public void onEvent(List<OnlineClient> onlineClients) {
SessionListFragmentNew.this.onlineClients = onlineClients;
if (onlineClients == null || onlineClients.size() == 0) {
// multiportBar.setVisibility(View.GONE);
} else {
// multiportBar.setVisibility(View.VISIBLE);
// TextView status = multiportBar.findViewById(R.id.multiport_desc_label);
OnlineClient client = onlineClients.get(0);
for (OnlineClient temp : onlineClients) {
Log.d(TAG, "type : " + temp.getClientType() + " , customTag : " + temp.getCustomTag());
}
switch (client.getClientType()) {
case ClientType.Windows:
case ClientType.MAC:
// status.setText(getString(R.string.multiport_logging) + getString(R.string.computer_version));
break;
case ClientType.Web:
// status.setText(getString(R.string.multiport_logging) + getString(R.string.web_version));
break;
case ClientType.iOS:
case ClientType.Android:
// status.setText(getString(R.string.multiport_logging) + getString(R.string.mobile_version));
break;
default:
// multiportBar.setVisibility(View.GONE);
break;
}
}
}
};
// 重启app
public void restartAPP() {
// 注销账号,清除该账号的所有文件,
DataCleanManager.cleanApplicationData(getActivity());
// ECNotificationManager.getInstance().forceCancelNotification();
Intent intent = new Intent(getActivity(), LoginNewActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}
/**
* 处理退出操作
*/
private void handleLogout() {
try {
ECPreferences.savePreference(
ECPreferenceSettings.SETTINGS_FULLY_EXIT, false, true);
// 1登入系统 2退出系统 3专家客户端在手机前台运行 4.专家客户端在手机后台运行
BaseActivity.foreBack(getActivity(), 2);
android.os.Process.killProcess(android.os.Process.myPid());
return;
} catch (InvalidClassException e) {
e.printStackTrace();
}
}
private void kickOut(StatusCode code) {
Preferences.saveUserToken("");
if (code == StatusCode.PWD_ERROR) {
LogUtil.e("Auth", "user password error");
// ToastHelper.showToast(getActivity(), R.string.login_failed);
} else {
LogUtil.i("Auth", "Kicked!");
}
if (code == StatusCode.DATA_UPGRADE) {
// onLogout(getString(R.string.kickout_encrypt_database));
} else {
onLogout("");
}
}
// 注销
private void onLogout(String desc) {
// 清理缓存&注销监听&清除状态
// LogoutHelper.logout();
// LoginActivity.start(getActivity(), true, desc);
getActivity().finish();
}
// 将最近联系人列表fragment动态集成进来。 开发者也可以使用在xml中配置的方式静态集成。
private void addRecentContactsFragment() {
fragment = new RecentContactsFragment();
// fragment.setContainerId(R.id.messages_fragment);
// final UI activity = (UI) getActivity();
//
// // 如果是activity从堆栈恢复,FM中已经存在恢复而来的fragment,此时会使用恢复来的,而new出来这个会被丢弃掉
getActivity().getSupportFragmentManager().beginTransaction().add(R.id.messages_fragment,fragment).commit();
fragment.setCallback(new RecentContactsCallback() {
@Override
public void onRecentContactsLoaded() {
// 最近联系人列表加载完毕
int a=0;
}
@Override
public void onUnreadCountChange(int unreadCount) {
ReminderManager.getInstance().updateSessionUnreadNum(unreadCount);
}
@Override
public void onItemClick(RecentContact recent,int p) {
// 回调函数,以供打开会话窗口时传入定制化参数,或者做其他动作
switch (recent.getSessionType()) {
case P2P:
// SessionHelper.startP2PSession(getActivity(), recent.getContactId());
// if(recent.getContactId().contains("#"))
// start(getActivity(), recent.getContactId().split("#")[1].toLowerCase(), null, null,general,"");
// else
startfor(getActivity(), recent.getContactId(), null, null,general,"",p);
// start(getActivity(), recent.getContactId(), null, null,general,"");
break;
case Team:
SessionHelper.startTeamSession(getActivity(), recent.getContactId());
break;
case SUPER_TEAM:
ToastHelper.showToast(getActivity(), "超大群开发者按需实现");
break;
case Ysf:
// Unicorn.openServiceActivity(getContext(), "七鱼测试", null);
break;
default:
break;
}
}
@Override
public String getDigestOfAttachment(RecentContact recentContact, MsgAttachment attachment) {
// 设置自定义消息的摘要消息,展示在最近联系人列表的消息缩略栏上
// 当然,你也可以自定义一些内建消息的缩略语,例如图片,语音,音视频会话等,自定义的缩略语会被优先使用。
if (attachment instanceof GuessAttachment) {
GuessAttachment guess = (GuessAttachment) attachment;
return guess.getValue().getDesc();
}
// else if (attachment instanceof RTSAttachment) {
// return "[白板]";
// } else if (attachment instanceof StickerAttachment) {
// return "[贴图]";
// } else if (attachment instanceof SnapChatAttachment) {
// return "[阅后即焚]";
// }
else if (attachment instanceof RedPacketAttachment) {
return "[红包]";
} else if (attachment instanceof RedPacketOpenedAttachment) {
return ((RedPacketOpenedAttachment) attachment).getDesc(recentContact.getSessionType(), recentContact.getContactId());
} else if (attachment instanceof MultiRetweetAttachment){
return "[聊天记录]";
}
else if (attachment instanceof TeachAttachment){
return ((TeachAttachment) attachment).getType();
}
return null;
}
@Override
public String getDigestOfTipMsg(RecentContact recent) {
String msgId = recent.getRecentMessageId();
List<String> uuids = new ArrayList<>(1);
uuids.add(msgId);
List<IMMessage> msgs = NIMClient.getService(MsgService.class).queryMessageListByUuidBlock(uuids);
if (msgs != null && !msgs.isEmpty()) {
IMMessage msg = msgs.get(0);
Map<String, Object> content = msg.getRemoteExtension();
if (content != null && !content.isEmpty()) {
return (String) content.get("content");
}
}
return null;
}
});
}
@Override
public View onCreateSuccessedView() {
return null;
}
@Override
public LoadingPage.ResultState onLoad() {
return null;
}
}
@@ -0,0 +1,157 @@
package cn.shangyu.gdxzExpert.netease.main.viewholder;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.netease.nim.uikit.business.contact.core.item.AbsContactItem;
import com.netease.nim.uikit.business.contact.core.item.ItemTypes;
import com.netease.nim.uikit.business.contact.core.model.ContactDataAdapter;
import com.netease.nim.uikit.business.contact.core.viewholder.AbsContactViewHolder;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.DemoCache;
import cn.shangyu.gdxzExpert.netease.main.ReminderId;
import cn.shangyu.gdxzExpert.netease.main.ReminderItem;
import cn.shangyu.gdxzExpert.netease.main.ReminderManager;
import cn.shangyu.gdxzExpert.netease.main.SystemMessageUnreadManager;
import cn.shangyu.gdxzExpert.netease.session.SessionHelper;
import static cn.shangyu.gdxzExpert.utils.Constant.general;
public class FuncViewHolder extends AbsContactViewHolder<FuncViewHolder.FuncItem> implements ReminderManager.UnreadNumChangedCallback {
private static ArrayList<WeakReference<ReminderManager.UnreadNumChangedCallback>> sUnreadCallbackRefs = new ArrayList<>();
private ImageView image;
private TextView funcName;
private TextView unreadNum;
private Set<ReminderManager.UnreadNumChangedCallback> callbacks = new HashSet<>();
@Override
public View inflate(LayoutInflater inflater) {
View view = inflater.inflate(R.layout.func_contacts_item, null);
this.image = view.findViewById(R.id.img_head);
this.funcName = view.findViewById(R.id.tv_func_name);
this.unreadNum = view.findViewById(R.id.tab_new_msg_label);
return view;
}
@Override
public void refresh(ContactDataAdapter contactAdapter, int position, FuncItem item) {
if (item == FuncItem.VERIFY) {
funcName.setText("验证提醒");
// image.setImageResource(R.drawable.icon_verify_remind);
image.setScaleType(ImageView.ScaleType.FIT_XY);
int unreadCount = SystemMessageUnreadManager.getInstance().getSysMsgUnreadCount();
updateUnreadNum(unreadCount);
ReminderManager.getInstance().registerUnreadNumChangedCallback(this);
sUnreadCallbackRefs.add(new WeakReference<ReminderManager.UnreadNumChangedCallback>(this));
} else if (item == FuncItem.ROBOT) {
funcName.setText("智能机器人");
// image.setImageResource(R.drawable.ic_robot);
} else if (item == FuncItem.NORMAL_TEAM) {
funcName.setText("讨论组");
// image.setImageResource(R.drawable.ic_secretary);
} else if (item == FuncItem.ADVANCED_TEAM) {
funcName.setText("高级群");
// image.setImageResource(R.drawable.ic_advanced_team);
} else if (item == FuncItem.BLACK_LIST) {
funcName.setText("黑名单");
// image.setImageResource(R.drawable.ic_black_list);
} else if (item == FuncItem.MY_COMPUTER) {
funcName.setText("我的电脑");
// image.setImageResource(R.drawable.ic_my_computer);
}
if (item != FuncItem.VERIFY) {
image.setScaleType(ImageView.ScaleType.FIT_XY);
unreadNum.setVisibility(View.GONE);
}
}
private void updateUnreadNum(int unreadCount) {
// 2.*版本viewholder复用问题
if (unreadCount > 0 && funcName.getText().toString().equals("验证提醒")) {
unreadNum.setVisibility(View.VISIBLE);
unreadNum.setText("" + unreadCount);
} else {
unreadNum.setVisibility(View.GONE);
}
}
@Override
public void onUnreadNumChanged(ReminderItem item) {
if (item.getId() != ReminderId.CONTACT) {
return;
}
updateUnreadNum(item.getUnread());
}
public static void unRegisterUnreadNumChangedCallback() {
Iterator<WeakReference<ReminderManager.UnreadNumChangedCallback>> iter = sUnreadCallbackRefs.iterator();
while (iter.hasNext()) {
ReminderManager.getInstance().unregisterUnreadNumChangedCallback(iter.next().get());
iter.remove();
}
}
public final static class FuncItem extends AbsContactItem {
static final FuncItem VERIFY = new FuncItem();
static final FuncItem ROBOT = new FuncItem();
static final FuncItem NORMAL_TEAM = new FuncItem();
static final FuncItem ADVANCED_TEAM = new FuncItem();
static final FuncItem BLACK_LIST = new FuncItem();
static final FuncItem MY_COMPUTER = new FuncItem();
@Override
public int getItemType() {
return ItemTypes.FUNC;
}
@Override
public String belongsGroup() {
return null;
}
public static List<AbsContactItem> provide() {
List<AbsContactItem> items = new ArrayList<>();
items.add(VERIFY);
//items.add(ROBOT);
items.add(NORMAL_TEAM);
items.add(ADVANCED_TEAM);
items.add(BLACK_LIST);
items.add(MY_COMPUTER);
return items;
}
public static void handle(Context context, AbsContactItem item) {
if (item == VERIFY) {
// SystemMessageActivity.start(context);
} else if (item == ROBOT) {
// RobotListActivity.start(context);
} else if (item == NORMAL_TEAM) {
// TeamListActivity.start(context, ItemTypes.TEAMS.NORMAL_TEAM);
} else if (item == ADVANCED_TEAM) {
// TeamListActivity.start(context, ItemTypes.TEAMS.ADVANCED_TEAM);
} else if (item == MY_COMPUTER) {
SessionHelper.startP2PSession(context, DemoCache.getAccount(),general,"");
} else if (item == BLACK_LIST) {
// BlackListActivity.start(context);
}
}
}
}
@@ -0,0 +1,35 @@
package cn.shangyu.gdxzExpert.netease.mixpush;
import com.huawei.hms.push.RemoteMessage;
import com.netease.nim.uikit.common.util.log.sdk.wrapper.NimLog;
import com.netease.nimlib.sdk.mixpush.HWPushMessageService;
public class DemoHwPushMessageService extends HWPushMessageService {
private static final String TAG = "DemoHwPushMessageService";
public void onNewToken(String token) {
NimLog.i(TAG, " onNewToken, token=" + token);
}
/**
* 透传消息, 需要用户自己弹出通知
*
* @param remoteMessage
*/
public void onMessageReceived(RemoteMessage remoteMessage) {
NimLog.i(TAG, " onMessageReceived");
}
public void onMessageSent(String s) {
NimLog.i(TAG, " onMessageSent");
}
public void onDeletedMessages() {
NimLog.i(TAG, " onDeletedMessages");
}
public void onSendError(String var1, Exception var2) {
NimLog.e(TAG, " onSendError, " + var1, var2);
}
}
@@ -0,0 +1,132 @@
package cn.shangyu.gdxzExpert.netease.mixpush;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.NimIntent;
import com.netease.nimlib.sdk.StatusBarNotificationConfig;
import com.netease.nimlib.sdk.mixpush.MixPushMessageHandler;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import java.util.ArrayList;
import java.util.Map;
import cn.shangyu.gdxzExpert.big.activity.NormNewPatientActivity;
import cn.shangyu.gdxzExpert.netease.DemoCache;
import cn.shangyu.gdxzExpert.umeng.NewSystemMessageActivity;
import cn.shangyu.gdxzExpert.utils.StringUtil;
/**
* Created by hzchenkang on 2016/11/10.
*/
public class DemoMixPushMessageHandler implements MixPushMessageHandler {
public static final String PAYLOAD_SESSION_ID = "sessionID";
public static final String PAYLOAD_SESSION_TYPE = "sessionType";
// 对于华为推送,这个方法并不能保证一定会回调
@Override
public boolean onNotificationClicked(Context context, Map<String, String> payload) {
LogUtil.i(DemoMixPushMessageHandler.class.getSimpleName(), "rev pushMessage payload " + payload);
String sessionId = payload.get(PAYLOAD_SESSION_ID);
String type = payload.get(PAYLOAD_SESSION_TYPE);
// if(!StringUtil.isEmpty(payload.get("message_id")))
// {
// readMessage(payload.get("message_id"));
// }
String pushType = payload.get("type");
LogUtil.i(DemoMixPushMessageHandler.class.getSimpleName(), "pushType " + pushType);
if(pushType!=null)
{
Intent intent = new Intent();
switch (pushType)
{
case "12":
case "14":
intent.setClass(context, NormNewPatientActivity.class);
if(!StringUtil.isEmpty(payload.get("message_id")))
{
intent.putExtra("message_id",(payload.get("message_id")));
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
break;
case "39"://撤销随访
case "13":
intent.setClass(context, NewSystemMessageActivity.class);
if(!StringUtil.isEmpty(payload.get("message_id")))
{
intent.putExtra("message_id",(payload.get("message_id")));
}
intent.putExtra("module",2);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
break;
}
return true;
}
else if (sessionId != null && type != null) {
int typeValue = Integer.valueOf(type);
ArrayList<IMMessage> imMessages = new ArrayList<>();
IMMessage imMessage = MessageBuilder.createEmptyMessage(sessionId, SessionTypeEnum.typeOfValue(typeValue), 0);
imMessages.add(imMessage);
Intent notifyIntent = new Intent();
notifyIntent.setComponent(initLaunchComponent(context));
notifyIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
notifyIntent.setAction(Intent.ACTION_VIEW);
notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 必须
notifyIntent.putExtra(NimIntent.EXTRA_NOTIFY_CONTENT, imMessages);
context.startActivity(notifyIntent);
return true;
} else {
return false;
}
}
private ComponentName initLaunchComponent(Context context) {
ComponentName launchComponent;
StatusBarNotificationConfig config = DemoCache.getNotificationConfig();
Class<? extends Activity> entrance = config.notificationEntrance;
if (entrance == null) {
launchComponent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent();
} else {
launchComponent = new ComponentName(context, entrance);
}
return launchComponent;
}
// 将音视频通知 Notification 缓存,清除所有通知后再次弹出 Notification,避免清除之后找不到打开正在进行音视频通话界面的入口
@Override
public boolean cleanMixPushNotifications(int pushType) {
Context context = DemoCache.getContext();
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) {
manager.cancelAll();
// SparseArray<Notification> nos = AVChatKit.getNotifications();
// if (nos != null) {
// int key = 0;
// for (int i = 0; i < nos.size(); i++) {
// key = nos.keyAt(i);
// manager.notify(key, nos.get(key));
// }
// }
}
return true;
}
}
@@ -0,0 +1,87 @@
package cn.shangyu.gdxzExpert.netease.mixpush;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import com.netease.nim.uikit.api.model.main.CustomPushContentProvider;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
/**
* 示例:
* 1.自定义的推送文案
* 2.自定义推送 payload 实现特定的点击通知栏跳转行为{@link DemoMixPushMessageHandler}
* <p>
* 如果自定义文案和payload,请开发者在各端发送消息时保持一致。
*/
public class DemoPushContentProvider implements CustomPushContentProvider {
@Override
public String getPushContent(IMMessage message) {
return null;
}
@Override
public Map<String, Object> getPushPayload(IMMessage message) {
// HashMap<String, Object> payload = new HashMap<>();
// payload.put("apns-collapse-id", "321");
// payload.put("apns-from-id", NimUIKit.getAccount());
// return payload;
return getPayload(message);
}
private Map<String, Object> getPayload(IMMessage message) {
if (message == null) {
return null;
}
HashMap<String, Object> payload = new HashMap<>();
int sessionType = message.getSessionType().getValue();
payload.put("sessionType", sessionType);
String sessionId = "";
if (message.getSessionType() == SessionTypeEnum.Team) {
sessionId = message.getSessionId();
} else if (message.getSessionType() == SessionTypeEnum.P2P) {
sessionId = message.getFromAccount();
}
if (!TextUtils.isEmpty(sessionId)) {
payload.put("sessionID", sessionId);
}
//华为推送
setHwField(payload, sessionType, sessionId);
return payload;
}
private void setHwField(Map<String, Object> pushPayload, int sessionType, String sessionId) {
//hwField
Intent hwIntent = new Intent(Intent.ACTION_VIEW);
String intentStr = String.format(
"pushscheme://com.huawei.codelabpush/deeplink?sessionID=%s&sessionType=%s",
sessionId, sessionType
);
hwIntent.setData(Uri.parse(intentStr));
hwIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
String intentUri = hwIntent.toUri(Intent.URI_INTENT_SCHEME);
//点击事件的内容
JSONObject clickAction = new JSONObject();
//通知的内容
JSONObject notification = new JSONObject();
try {
clickAction.putOpt("type", 1)
.putOpt("intent", intentUri);
notification.putOpt("click_action", clickAction);
pushPayload.put("hwField", notification);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,58 @@
package cn.shangyu.gdxzExpert.netease.mixpush;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.Nullable;
import com.netease.nim.uikit.common.util.log.sdk.wrapper.NimLog;
import java.util.HashMap;
import java.util.Set;
public class MixPushActivity extends Activity {
private static final String TAG = "MixPushActivity";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NimLog.i(TAG, "mix_push onCreate");
parseIntent();
finish();
}
void parseIntent() {
Intent intent = getIntent();
if (intent == null) {
return;
}
Uri uri = intent.getData();
Bundle bundle = intent.getExtras();
HashMap<String, String> map;
if (uri != null) {
Set<String> parameterSet = uri.getQueryParameterNames();
map = new HashMap<>((parameterSet.size() << 2) / 3 + 1);
String value;
for (String p : parameterSet) {
value = uri.getQueryParameter(p);
if (value == null) {
continue;
}
map.put(p, value);
}
} else if (bundle != null) {
map = new HashMap<>((bundle.size() << 2) / 3 + 1);
for (String key : bundle.keySet()) {
Object valueObj = bundle.get(key);
map.put(key, valueObj == null ? null : valueObj.toString());
}
} else {
map = new HashMap<>(0);
}
new DemoMixPushMessageHandler().onNotificationClicked(this.getApplicationContext(), map);
}
}
@@ -0,0 +1,8 @@
package cn.shangyu.gdxzExpert.netease.model;
public interface Extras {
// 参数
String EXTRA_ACCOUNT = "account";
}
@@ -0,0 +1,58 @@
package cn.shangyu.gdxzExpert.netease.model;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.main.ReminderId;
import cn.shangyu.gdxzExpert.netease.main.fragment.ChatRoomListFragment;
import cn.shangyu.gdxzExpert.netease.main.fragment.ContactListFragment;
import cn.shangyu.gdxzExpert.netease.main.fragment.MainTabFragment;
import cn.shangyu.gdxzExpert.netease.main.fragment.SessionListFragment;
public enum MainTab {
RECENT_CONTACTS(0, ReminderId.SESSION, SessionListFragment.class, com.netease.nim.uikit.R.string.main_tab_session, R.layout.session_list),
CONTACT(1, ReminderId.CONTACT, ContactListFragment.class, com.netease.nim.uikit.R.string.main_tab_contact, R.layout.contacts_list),
CHAT_ROOM(2, ReminderId.INVALID, ChatRoomListFragment.class, com.netease.nim.uikit.R.string.chat_room, R.layout.session_list);
public final int tabIndex;
public final int reminderId;
public final Class<? extends MainTabFragment> clazz;
public final int resId;
public final int fragmentId;
public final int layoutId;
MainTab(int index, int reminderId, Class<? extends MainTabFragment> clazz, int resId, int layoutId) {
this.tabIndex = index;
this.reminderId = reminderId;
this.clazz = clazz;
this.resId = resId;
this.fragmentId = index;
this.layoutId = layoutId;
}
public static final MainTab fromReminderId(int reminderId) {
for (MainTab value : MainTab.values()) {
if (value.reminderId == reminderId) {
return value;
}
}
return null;
}
public static final MainTab fromTabIndex(int tabIndex) {
for (MainTab value : MainTab.values()) {
if (value.tabIndex == tabIndex) {
return value;
}
}
return null;
}
}
@@ -0,0 +1,103 @@
package cn.shangyu.gdxzExpert.netease.model;
/**
* Created by hzxuwen on 2015/6/29.
*/
public class SettingTemplate {
private int id;
private int icon;
private int type;
private String title; // left title
private String detail; // right detail
private boolean visible;
private boolean checked;
private int checkedId; // type==TYPE_THREE_CHOOSE_ONE; 默认被选中项的ID
public SettingTemplate(int id, String title) {
this(id, title, 0);
}
public SettingTemplate(int id, int type) {
this(id, null, type, 0);
}
public SettingTemplate(int id, String title, String detail) {
this(id, title, 0);
this.detail = detail;
}
public SettingTemplate(int id, String title, int type) {
this(id, title, type, 0);
}
public SettingTemplate(int id, String title, int type, boolean checked) {
this(id, title, type, 0);
this.checked = checked;
}
public SettingTemplate(int id, String title, int type, Void icon, int checkedId) {
this(id, title, type, 0);
this.checkedId = checkedId;
}
public SettingTemplate(int id, String title, int type, int icon) {
this.id = id;
this.icon = icon;
this.title = title;
this.type = type;
this.visible = true;
}
public static SettingTemplate makeSeperator() {
return new SettingTemplate(0, SettingType.TYPE_SEPERATOR);
}
public static SettingTemplate addLine() {
return new SettingTemplate(0, SettingType.TYPE_LINE);
}
public int getId() {
return id;
}
public int getIcon() {
return icon;
}
public int getType() {
return type;
}
public String getTitle() {
return title;
}
public void setDetail(String detail) {
this.detail = detail;
}
public String getDetail() {
return detail;
}
public boolean isVisible() {
return visible;
}
public boolean getChekced() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public int getCheckedId() {
return this.checkedId;
}
public void setCheckedId(int checkedId) {
this.checkedId = checkedId;
}
}
@@ -0,0 +1,13 @@
package cn.shangyu.gdxzExpert.netease.model;
/**
* Created by hzxuwen on 2015/6/30.
*/
public interface SettingType {
int TYPE_DEFAULE = 1;
int TYPE_TOGGLE = 2;
int TYPE_HEAD = 3;
int TYPE_SEPERATOR = 4;
int TYPE_LINE = 5;
int TYPE_THREE_CHOOSE_ONE = 6;
}
@@ -0,0 +1,172 @@
package cn.shangyu.gdxzExpert.netease.ptop;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import androidx.appcompat.widget.Toolbar;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.netease.nim.uikit.R;
import com.netease.nim.uikit.api.model.session.SessionCustomization;
import com.netease.nim.uikit.business.preference.UserPreferences;
import com.netease.nim.uikit.business.session.audio.MessageAudioControl;
import com.netease.nim.uikit.business.session.constant.Extras;
import com.netease.nim.uikit.common.CommonUtil;
import com.netease.nim.uikit.common.activity.UI;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import java.util.List;
/**
* Created by zhoujianghua on 2015/9/10.
*/
public abstract class BaseMessageActivity extends UI {
protected String sessionId;
private SessionCustomization customization;
public MessageFragment messageFragment;
private SensorManager sensorManager;
private Sensor proximitySensor;
protected abstract cn.shangyu.gdxzExpert.netease.ptop.MessageFragment fragment();
protected abstract int getContentViewId();
protected abstract void initToolBar();
/**
* 是否开启距离传感器
*/
protected abstract boolean enableSensor();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentViewId());
initToolBar();
parseIntent();
messageFragment = (MessageFragment) switchContent(fragment());
if (enableSensor()) {
initSensor();
}
}
@Override
protected void onResume() {
super.onResume();
if (sensorManager != null && proximitySensor != null) {
sensorManager.registerListener(sensorEventListener, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}
@Override
protected void onPause() {
super.onPause();
if (sensorManager != null && proximitySensor != null) {
sensorManager.unregisterListener(sensorEventListener);
}
}
@Override
public void onBackPressed() {
if (messageFragment != null && messageFragment.onBackPressed()) {
return;
}
super.onBackPressed();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (messageFragment != null) {
messageFragment.onActivityResult(requestCode, resultCode, data);
}
if (customization != null) {
customization.onActivityResult(this, requestCode, resultCode, data);
}
}
private void parseIntent() {
Intent intent = getIntent();
sessionId = intent.getStringExtra(Extras.EXTRA_ACCOUNT);
customization = (SessionCustomization) intent.getSerializableExtra(Extras.EXTRA_CUSTOMIZATION);
if (customization != null) {
addRightCustomViewOnActionBar(this, customization.buttons);
}
}
// 添加action bar的右侧按钮及响应事件
private void addRightCustomViewOnActionBar(UI activity, List<SessionCustomization.OptionsButton> buttons) {
if (CommonUtil.isEmpty(buttons)) {
return;
}
Toolbar toolbar = getToolBar();
if (toolbar == null) {
return;
}
LinearLayout buttonContainer = (LinearLayout) LayoutInflater.from(activity).inflate(R.layout.nim_action_bar_custom_view, null);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
for (final SessionCustomization.OptionsButton button : buttons) {
ImageView imageView = new ImageView(activity);
imageView.setImageResource(button.iconId);
imageView.setBackgroundResource(R.drawable.nim_nim_action_bar_button_selector);
imageView.setPadding(ScreenUtil.dip2px(10), 0, ScreenUtil.dip2px(10), 0);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
button.onClick(BaseMessageActivity.this, v, sessionId);
}
});
buttonContainer.addView(imageView, params);
}
toolbar.addView(buttonContainer, new Toolbar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.RIGHT | Gravity.CENTER));
}
private SensorEventListener sensorEventListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float[] dis = event.values;
if (0.0f == dis[0]) {
//靠近,设置为听筒模式
MessageAudioControl.getInstance(BaseMessageActivity.this).setEarPhoneModeEnable(true);
} else {
//离开,复原
MessageAudioControl.getInstance(BaseMessageActivity.this).setEarPhoneModeEnable(UserPreferences.isEarPhoneModeEnable());
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
private void initSensor() {
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager != null) {
proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
}
}
}
@@ -0,0 +1,61 @@
package cn.shangyu.gdxzExpert.netease.ptop;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseQuickAdapter;
import com.netease.nim.uikit.impl.NimUIKitImpl;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
public class CommonRecentViewHolder extends RecentViewHolder {
CommonRecentViewHolder(BaseQuickAdapter adapter) {
super(adapter);
}
@Override
protected String getContent(RecentContact recent) {
return descOfMsg(recent);
}
@Override
protected String getOnlineStateContent(RecentContact recent) {
if (recent.getSessionType() == SessionTypeEnum.P2P && NimUIKitImpl.enableOnlineState()) {
return NimUIKitImpl.getOnlineStateContentProvider().getSimpleDisplay(recent.getContactId());
} else {
return super.getOnlineStateContent(recent);
}
}
String descOfMsg(RecentContact recent) {
if (recent.getMsgType() == MsgTypeEnum.text) {
return recent.getContent();
} else if (recent.getMsgType() == MsgTypeEnum.tip) {
String digest = null;
if (getCallback() != null) {
digest = getCallback().getDigestOfTipMsg(recent);
}
if (digest == null) {
digest = NimUIKitImpl.getRecentCustomization().getDefaultDigest(recent);
}
return digest;
} else if (recent.getAttachment() != null) {
String digest = null;
if (getCallback() != null) {
digest = getCallback().getDigestOfAttachment(recent, recent.getAttachment());
}
if (digest == null) {
digest = NimUIKitImpl.getRecentCustomization().getDefaultDigest(recent);
}
return digest;
} else if (recent.getSessionType() == SessionTypeEnum.Ysf) {
return recent.getContent();
}
return "[未知]";
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,548 @@
package cn.shangyu.gdxzExpert.netease.ptop;
import static cn.shangyu.gdxzExpert.ecdemo.common.utils.CommomUtil.simpleDateFormat;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import androidx.appcompat.widget.Toolbar;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gyf.immersionbar.ImmersionBar;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.model.contact.ContactChangedObserver;
import com.netease.nim.uikit.api.model.main.OnlineStateChangeObserver;
import com.netease.nim.uikit.api.model.session.SessionCustomization;
import com.netease.nim.uikit.api.model.user.UserInfoObserver;
import com.netease.nim.uikit.business.session.constant.Extras;
import com.netease.nim.uikit.common.ToastHelper;
import com.netease.nim.uikit.impl.NimUIKitImpl;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.StatusCode;
import com.netease.nimlib.sdk.auth.AuthService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.CustomNotification;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import org.json.JSONException;
import java.util.Date;
import java.util.List;
import java.util.Set;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.activity.LoginNewActivity;
import cn.shangyu.gdxzExpert.activity.PatientEditActivity;
import cn.shangyu.gdxzExpert.ecdemo.view.TopBarViewNew;
import cn.shangyu.gdxzExpert.http.HttpHelper;
import cn.shangyu.gdxzExpert.netease.config.LogoutHelper;
import cn.shangyu.gdxzExpert.netease.uinfo.UserInfoHelper;
import cn.shangyu.gdxzExpert.utils.Constant;
import cn.shangyu.gdxzExpert.utils.StringUtil;
import cn.shangyu.gdxzExpert.utils.ToastUtil;
import cn.shangyu.gdxzExpert.utils.Url;
import cn.shangyu.gdxzExpert.widget.ECAlertDialog;
/**
* 点对点聊天界面
* <p/>
* Created by huangjun on 2015/2/1.
*/
public class P2PMessageActivity extends BaseMessageActivity implements View.OnClickListener{
private boolean isResume = false;
private TopBarViewNew topBarView;
public static int position=-1;
public static int temposition=-1;
public static void start(Context context, String contactId,
SessionCustomization customization, IMMessage anchor,String gdxz_sessionType
,String state) {
Intent intent = new Intent();
intent.putExtra(Extras.EXTRA_ACCOUNT, contactId);
intent.putExtra(Extras.EXTRA_CUSTOMIZATION, customization);
intent.putExtra(Extras.EXTRA_GDXZ_TYPE,gdxz_sessionType);
intent.putExtra("chat_state",state);
if (anchor != null) {
intent.putExtra(Extras.EXTRA_ANCHOR, anchor);
}
intent.setClass(context, P2PMessageActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
position=-1;
context.startActivity(intent);
}
public static void start(Context context, String contactId,
SessionCustomization customization, IMMessage anchor,String gdxz_sessionType
,String state,String name) {
Intent intent = new Intent();
intent.putExtra(Extras.EXTRA_ACCOUNT, contactId);
intent.putExtra(Extras.EXTRA_CUSTOMIZATION, customization);
intent.putExtra(Extras.EXTRA_GDXZ_TYPE,gdxz_sessionType);
intent.putExtra("chat_state",state);
intent.putExtra(Extras.EXTRA_GDXZ_NICKNAME,name);
if (anchor != null) {
intent.putExtra(Extras.EXTRA_ANCHOR, anchor);
}
intent.setClass(context, P2PMessageActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
position=-1;
context.startActivity(intent);
}
public static void startfor(Context context, String contactId,
SessionCustomization customization, IMMessage anchor,String gdxz_sessionType
,String state,int position1) {
Intent intent = new Intent();
intent.putExtra(Extras.EXTRA_ACCOUNT, contactId);
intent.putExtra(Extras.EXTRA_CUSTOMIZATION, customization);
intent.putExtra(Extras.EXTRA_GDXZ_TYPE,gdxz_sessionType);
intent.putExtra("chat_state",state);
if (anchor != null) {
intent.putExtra(Extras.EXTRA_ANCHOR, anchor);
}
intent.setClass(context, P2PMessageActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
temposition=position1;
context.startActivity(intent);
}
public static void startwithId(Context context, String contactId,
SessionCustomization customization, IMMessage anchor,String gdxz_sessionType
,String state,String msd_id,String name) {
Intent intent = new Intent();
intent.putExtra(Extras.EXTRA_ACCOUNT, contactId);
intent.putExtra(Extras.EXTRA_CUSTOMIZATION, customization);
intent.putExtra(Extras.EXTRA_GDXZ_TYPE,gdxz_sessionType);
intent.putExtra("chat_state",state);
intent.putExtra("msd_id",msd_id);
intent.putExtra(Extras.EXTRA_GDXZ_NICKNAME,name);
if (anchor != null) {
intent.putExtra(Extras.EXTRA_ANCHOR, anchor);
}
intent.setClass(context, P2PMessageActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
public static void startwithId(Context context, String contactId,
SessionCustomization customization, IMMessage anchor,String gdxz_sessionType
,String state,String msd_id) {
Intent intent = new Intent();
intent.putExtra(Extras.EXTRA_ACCOUNT, contactId);
intent.putExtra(Extras.EXTRA_CUSTOMIZATION, customization);
intent.putExtra(Extras.EXTRA_GDXZ_TYPE,gdxz_sessionType);
intent.putExtra("chat_state",state);
intent.putExtra("msd_id",msd_id);
if (anchor != null) {
intent.putExtra(Extras.EXTRA_ANCHOR, anchor);
}
intent.setClass(context, P2PMessageActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
public Boolean isPopup1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 单聊特例话数据,包括个人信息,
// requestBuddyInfo();
displayOnlineState();
registerObservers(true);
topBarView=findView(R.id.topbar);
Toolbar mToolbar=findViewById(R.id.toolbar);
ImmersionBar.with(this).keyboardEnable(true).statusBarDarkFont(true).titleBar(mToolbar).init();
if(!StringUtil.isEmpty(getIntent().getStringExtra(Extras.EXTRA_GDXZ_TYPE))
&&getIntent().getStringExtra(Extras.EXTRA_GDXZ_TYPE).equals(Constant.consult))
{
String actionBtn = getString(R.string.icon_closeMesg);
if(!StringUtil.isEmpty(getIntent().getStringExtra(Extras.EXTRA_GDXZ_NICKNAME)))
{
topBarView.setTopBarToStatus(1, R.drawable.topbar_back_bt,
R.drawable.btn_style_brown, null, actionBtn,getIntent().getStringExtra(Extras.EXTRA_GDXZ_NICKNAME),
null, this);
}
else
{
topBarView.setTopBarToStatus(1, R.drawable.topbar_back_bt,
R.drawable.btn_style_brown, null, actionBtn, UserInfoHelper.getUserTitleName(sessionId, SessionTypeEnum.P2P),
null, this);
}
if(!StringUtil.isEmpty(getIntent().getStringExtra("chat_state"))
&&getIntent().getStringExtra("chat_state").equals("3"))
{
topBarView.setRightBtnVis(View.GONE);
}
}
else
{
// String actionBtn = getString(R.string.icon_closeMesg);
if(!StringUtil.isEmpty(getIntent().getStringExtra(Extras.EXTRA_GDXZ_NICKNAME)))
{
topBarView.setTopBarToStatus(1, R.drawable.topbar_back_bt,
R.drawable.more, null, null, getIntent().getStringExtra(Extras.EXTRA_GDXZ_NICKNAME),
null, this);
}
else
{
topBarView.setTopBarToStatus(1, R.drawable.topbar_back_bt,
R.drawable.more, null, null, UserInfoHelper.getUserTitleName(sessionId, SessionTypeEnum.P2P),
null, this);
}
// topBarView.setTopBarToStatus(1, R.drawable.topbar_back_bt,
// R.drawable.actionbar_particular_icon, UserInfoHelper.getUserTitleName(sessionId, SessionTypeEnum.P2P), this);
}
// UserUpdateHelper.update(UserInfoFieldEnum.AVATAR, UserInfoHelper.getUserDisplayPhoto(sessionId), new RequestCallbackWrapper<Void>() {
// @Override
// public void onResult(int code, Void result, Throwable exception) {
//
// }
// });
// UserUpdateHelper.update(UserInfoFieldEnum.AVATAR, UserInfoHelper.getUserDisplayPhoto(NimUIKit.getAccount()), new RequestCallbackWrapper<Void>() {
// @Override
// public void onResult(int code, Void result, Throwable exception) {
//
//
// }
// });
}
@Override
protected void onDestroy() {
super.onDestroy();
registerObservers(false);
}
@Override
protected void onResume() {
super.onResume();
isResume = true;
// ImmersionBar.with(this).keyboardEnable(true).statusBarDarkFont(true).titleBar(topBarView).init();
}
@Override
protected void onStop() {
super.onStop();
isResume = false;
}
private void requestBuddyInfo() {
setTitle(UserInfoHelper.getUserTitleName(sessionId, SessionTypeEnum.P2P));
}
private void displayOnlineState() {
if (!NimUIKitImpl.enableOnlineState()) {
return;
}
String detailContent = NimUIKitImpl.getOnlineStateContentProvider().getDetailDisplay(sessionId);
setSubTitle(detailContent);
}
/**
* 命令消息接收观察者
*/
private Observer<CustomNotification> commandObserver = new Observer<CustomNotification>() {
@Override
public void onEvent(CustomNotification message) {
if (!sessionId.equals(message.getSessionId()) || message.getSessionType() != SessionTypeEnum.P2P) {
return;
}
showCommandMessage(message);
}
};
/**
* 用户信息变更观察者
*/
private UserInfoObserver userInfoObserver = new UserInfoObserver() {
@Override
public void onUserInfoChanged(List<String> accounts) {
if (!accounts.contains(sessionId)) {
return;
}
// requestBuddyInfo();
}
};
/**
* 好友资料变更(eg:关系)
*/
private ContactChangedObserver friendDataChangedObserver = new ContactChangedObserver() {
@Override
public void onAddedOrUpdatedFriends(List<String> accounts) {
setTitle(UserInfoHelper.getUserTitleName(sessionId, SessionTypeEnum.P2P));
}
@Override
public void onDeletedFriends(List<String> accounts) {
setTitle(UserInfoHelper.getUserTitleName(sessionId, SessionTypeEnum.P2P));
}
@Override
public void onAddUserToBlackList(List<String> account) {
setTitle(UserInfoHelper.getUserTitleName(sessionId, SessionTypeEnum.P2P));
}
@Override
public void onRemoveUserFromBlackList(List<String> account) {
setTitle(UserInfoHelper.getUserTitleName(sessionId, SessionTypeEnum.P2P));
}
};
/**
* 好友在线状态观察者
*/
private OnlineStateChangeObserver onlineStateChangeObserver = new OnlineStateChangeObserver() {
@Override
public void onlineStateChange(Set<String> accounts) {
if (!accounts.contains(sessionId)) {
return;
}
// 按照交互来展示
displayOnlineState();
}
};
private void registerObservers(boolean register) {
NIMClient.getService(MsgServiceObserve.class).observeCustomNotification(commandObserver, register);
NimUIKit.getUserInfoObservable().registerObserver(userInfoObserver, register);
NimUIKit.getContactChangedObservable().registerObserver(friendDataChangedObserver, register);
if (NimUIKit.enableOnlineState()) {
NimUIKit.getOnlineStateChangeObservable().registerOnlineStateChangeListeners(onlineStateChangeObserver, register);
}
// NIMClient.getService(AuthServiceObserver.class).observeOnlineStatus(userStatusObserver, register);
}
protected void showCommandMessage(CustomNotification message) {
if (!isResume) {
return;
}
String content = message.getContent();
try {
JSONObject json = JSON.parseObject(content);
int id = json.getIntValue("id");
if (id == 1) {
// 正在输入
ToastHelper.showToastLong(P2PMessageActivity.this, "对方正在输入...");
} else {
ToastHelper.showToast(P2PMessageActivity.this, "command: " + content);
}
} catch (Exception ignored) {
}
}
/**
* 用户状态变化
*/
Observer<StatusCode> userStatusObserver = new Observer<StatusCode>() {
@Override
public void onEvent(StatusCode code) {
if (code.wontAutoLogin()) {
if(code!=StatusCode.PWD_ERROR)
{
LogoutHelper.logout();
showlogout();
}
}
}
};
private void showlogout()
{
Date date = new Date(System.currentTimeMillis());
String phone="ios";
switch(NIMClient.getService(AuthService.class).getKickedClientType())
{
case 1:
phone="android";
break;
case 2:
phone="ios";
break;
case 16:
phone="web";
break;
default:
phone="unknow";
break;
}
ECAlertDialog buildAlert = ECAlertDialog.buildAlert(this,
getString(R.string.nim_kick_out)+
simpleDateFormat.format(date)+getString(R.string.nim_kick_out1)+
phone+getString(R.string.nim_kick_out2)
, getString(R.string.dialog_btn_confim),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startActivity(new Intent(P2PMessageActivity.this, LoginNewActivity.class));
finish();
}
});
buildAlert.setTitle("异地登陆");
buildAlert.setCanceledOnTouchOutside(false);
buildAlert.setCancelable(false);
buildAlert.show();
}
@Override
protected MessageFragment fragment() {
Bundle arguments = getIntent().getExtras();
arguments.putSerializable(Extras.EXTRA_TYPE, SessionTypeEnum.P2P);
MessageFragment fragment = new MessageFragment();
fragment.setArguments(arguments);
fragment.setContainerId(R.id.message_fragment_container);
return fragment;
}
@Override
protected int getContentViewId() {
return R.layout.nim_message_activity_new;
}
@Override
protected void initToolBar() {
// ToolBarOptions options = new NimToolBarOptions();
// setToolBar(R.id.toolbar, options);
}
@Override
protected boolean enableSensor() {
return true;
}
@Override
public void onClick(View v) {
switch (v.getId())
{
case R.id.text_right:
RequestParams params = new RequestParams();
params.addBodyParameter("uuid", getIntent().getStringExtra("msd_id"));
HttpHelper.loadData(HttpRequest.HttpMethod.POST, Url.getcloseConsult, params,
new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> info) {
org.json.JSONObject objs;
String retcode = "";
String message = "";
try {
objs = new org.json.JSONObject(info.result);
retcode = objs.getString("code");
message = objs.getString("message");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ToastUtil.showToast("关闭失败,请重试");
}
if ("1".equals(retcode)) {
String closeText = "您已关闭会话,谢谢您的回答!";
closeText = getResources().getString(
R.string.close_public_service);
ToastUtil.showToast(closeText);
// mChattingFooter.goneChatFooterPanel();
// mChattingFooter.setVisibility(View.GONE);
topBarView.setRightBtnEnable(false);
messageFragment.bottom_layout.setVisibility(View.GONE);
// // 保存关闭的uuid
// SharePrefUtil.saveBoolean(UIUtils.getContext(),
// uuid, true);
// finish();
} else {
ToastUtil.showToast(message);
}
}
@Override
public void onFailure(HttpException arg0, String arg1) {
ToastUtil.showToast("关闭会话失败,请重试");
}
});
break;
case R.id.btn_left:
hideSoftInput();
finish();
break;
case R.id.btn_right:
// // 患者详情页面
// Intent intent = new Intent(UIUtils.getContext(),
// PatientActivity.class);
// intent.putExtra("realName", UserInfoHelper.getUserTitleName(sessionId, SessionTypeEnum.P2P));
// intent.putExtra("isFriend",false );
// String uuid = sessionId;
// if (sessionId.contains("#")) {
// String[] split = sessionId.split("#");
// uuid = split[1];
// }
// intent.putExtra("patientUuid", uuid);
// startActivity(intent);// 启动患者详情界面
// break;
// case R.id.btn_right2:
hideSoftInput();
String patientUuid = sessionId;
if (sessionId.contains("#")) {
String[] split = sessionId.split("#");
patientUuid = split[1];
}
Intent intent1 = new Intent(P2PMessageActivity.this, PatientEditActivity.class);
intent1.putExtra("patientUuid",patientUuid);
intent1.putExtra("needhead",true);
startActivityForResult(intent1,24);
break;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(data==null)
return;
if(requestCode==24)
{
position=temposition;
finish();
}
}
private void hideSoftInput()
{
View view = getWindow().peekDecorView();
if (view != null) {
InputMethodManager inputmanger = (InputMethodManager)P2PMessageActivity.this. getSystemService(Context.INPUT_METHOD_SERVICE);
inputmanger.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
}
@@ -0,0 +1,70 @@
package cn.shangyu.gdxzExpert.netease.ptop;
import androidx.recyclerview.widget.RecyclerView;
import com.netease.nim.uikit.business.recent.RecentContactsCallback;
import com.netease.nim.uikit.business.recent.holder.SuperTeamRecentViewHolder;
import com.netease.nim.uikit.business.recent.holder.TeamRecentViewHolder;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseMultiItemQuickAdapter;
import com.netease.nim.uikit.common.ui.recyclerview.holder.BaseViewHolder;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import java.util.List;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.big.BigCommonRecentViewHolder;
import cn.shangyu.gdxzExpert.utils.CommonUtil;
/**
* Created by huangjun on 2016/12/11.
*/
public class RecentContactAdapter extends BaseMultiItemQuickAdapter<RecentContact, BaseViewHolder> {
interface ViewType {
int VIEW_TYPE_COMMON = 1;
int VIEW_TYPE_TEAM = 2;
int VIEW_TYPE_SUPER_TEAM = 3;
}
private RecentContactsCallback callback;
public RecentContactAdapter(RecyclerView recyclerView, List<RecentContact> data) {
super(recyclerView, data);
if(CommonUtil.BigModule())
{
addItemType(ViewType.VIEW_TYPE_COMMON, R.layout.nim_recent_contact_list_item_big, BigCommonRecentViewHolder.class);
}
else
{
addItemType(ViewType.VIEW_TYPE_COMMON, R.layout.nim_recent_contact_list_item_new, BigCommonRecentViewHolder.class);
// addItemType(ViewType.VIEW_TYPE_COMMON, R.layout.nim_recent_contact_list_item, CommonRecentViewHolder.class);
}
addItemType(ViewType.VIEW_TYPE_TEAM, com.netease.nim.uikit.R.layout.nim_recent_contact_list_item, TeamRecentViewHolder.class);
addItemType(ViewType.VIEW_TYPE_SUPER_TEAM, com.netease.nim.uikit.R.layout.nim_recent_contact_list_item, SuperTeamRecentViewHolder.class);
}
@Override
protected int getViewType(RecentContact item) {
return item.getSessionType() == SessionTypeEnum.Team ? ViewType.VIEW_TYPE_TEAM : ViewType.VIEW_TYPE_COMMON;
}
@Override
protected String getItemKey(RecentContact item) {
StringBuilder sb = new StringBuilder();
sb.append(item.getSessionType().getValue()).append("_").append(item.getContactId());
return sb.toString();
}
public RecentContactsCallback getCallback() {
return callback;
}
public void setCallback(RecentContactsCallback callback) {
this.callback = callback;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,238 @@
package cn.shangyu.gdxzExpert.netease.ptop;
import android.graphics.drawable.AnimationDrawable;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.business.recent.RecentContactsCallback;
import com.netease.nim.uikit.business.session.emoji.MoonUtil;
import com.netease.nim.uikit.common.framework.infra.Handlers;
import com.netease.nim.uikit.common.ui.drop.DropFake;
import com.netease.nim.uikit.common.ui.drop.DropManager;
import com.netease.nim.uikit.common.ui.imageview.HeadImageView;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseQuickAdapter;
import com.netease.nim.uikit.common.ui.recyclerview.holder.BaseViewHolder;
import com.netease.nim.uikit.common.ui.recyclerview.holder.RecyclerViewHolder;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import com.netease.nim.uikit.common.util.sys.TimeUtil;
import com.netease.nim.uikit.impl.cache.StickTopCache;
import com.netease.nimlib.sdk.msg.constant.MsgStatusEnum;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.superteam.SuperTeam;
import com.netease.nimlib.sdk.team.model.Team;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.uinfo.UserInfoHelper;
import cn.shangyu.gdxzExpert.utils.StringUtil;
public abstract class RecentViewHolder extends RecyclerViewHolder<BaseQuickAdapter, BaseViewHolder, RecentContact> {
public RecentViewHolder(BaseQuickAdapter adapter) {
super(adapter);
}
private int lastUnreadCount = 0;
protected RelativeLayout portraitPanel;
protected HeadImageView imgHead;
protected TextView tvNickname;
protected TextView tvMessage;
protected TextView tvDatetime;
// 消息发送错误状态标记,目前没有逻辑处理
protected ImageView imgMsgStatus;
protected View bottomLine;
protected View topLine;
// 未读红点(一个占坑,一个全屏动画)
protected DropFake tvUnread;
private ImageView imgUnreadExplosion;
protected TextView tvOnlineState;
private static Integer labelWidth;
// 子类覆写
protected abstract String getContent(RecentContact recent);
@Override
public void convert(BaseViewHolder holder, RecentContact data, int position, boolean isScrolling) {
inflate(holder, data);
refresh(holder, data, position);
}
public void inflate(BaseViewHolder holder, final RecentContact recent) {
this.portraitPanel = holder.getView(R.id.portrait_panel);
this.imgHead = holder.getView(R.id.img_head);
this.tvNickname = holder.getView(R.id.tv_nickname);
this.tvMessage = holder.getView(R.id.tv_message);
this.tvUnread = holder.getView(R.id.unread_number_tip);
this.imgUnreadExplosion = holder.getView(R.id.unread_number_explosion);
this.tvDatetime = holder.getView(R.id.tv_date_time);
this.imgMsgStatus = holder.getView(R.id.img_msg_status);
this.bottomLine = holder.getView(R.id.bottom_line);
this.topLine = holder.getView(R.id.top_line);
this.tvOnlineState = holder.getView(R.id.tv_online_state);
holder.addOnClickListener(R.id.unread_number_tip);
this.tvUnread.setTouchListener(new DropFake.ITouchListener() {
@Override
public void onDown() {
DropManager.getInstance().setCurrentId(recent);
DropManager.getInstance().down(tvUnread, tvUnread.getText());
}
@Override
public void onMove(float curX, float curY) {
DropManager.getInstance().move(curX, curY);
}
@Override
public void onUp() {
DropManager.getInstance().up();
}
});
}
public void refresh(BaseViewHolder holder, RecentContact recent, final int position) {
// unread count animation
boolean shouldBoom = lastUnreadCount > 0 && recent.getUnreadCount() == 0; // 未读数从N->0执行爆裂动画;
lastUnreadCount = recent.getUnreadCount();
updateBackground(holder, recent, position);
loadPortrait(recent);
updateNickLabel(
UserInfoHelper.getUserTitleName(recent.getContactId(), recent.getSessionType())
);
updateOnlineState(recent);
updateMsgLabel(holder, recent);
updateNewIndicator(recent);
if (shouldBoom) {
Object o = DropManager.getInstance().getCurrentId();
if (o instanceof String && o.equals("0")) {
imgUnreadExplosion.setImageResource(com.netease.nim.uikit.R.drawable.nim_explosion);
imgUnreadExplosion.setVisibility(View.VISIBLE);
Handlers.sharedHandler(holder.getContext()).post(() -> {
((AnimationDrawable) imgUnreadExplosion.getDrawable()).start();
// 解决部分手机动画无法播放的问题(例如华为荣耀)
getAdapter().notifyItemChanged(getAdapter().getViewHolderPosition(position));
});
}
} else {
imgUnreadExplosion.setVisibility(View.GONE);
}
}
private void updateBackground(BaseViewHolder holder, RecentContact recent, int position) {
topLine.setVisibility(getAdapter().isFirstDataItem(position) ? View.GONE : View.VISIBLE);
bottomLine.setVisibility(getAdapter().isLastDataItem(position) ? View.VISIBLE : View.GONE);
holder.getConvertView().setBackgroundResource(recent == null || StickTopCache.isStickTop(recent) ?
com.netease.nim.uikit.R.drawable.nim_recent_contact_sticky_selecter : com.netease.nim.uikit.R.drawable.nim_touch_bg);
}
protected void loadPortrait(RecentContact recent) {
// 设置头像
if (recent.getSessionType() == SessionTypeEnum.P2P) {
// imgHead.loadBuddyAvatar(recent.getContactId());
if(!StringUtil.isEmpty(UserInfoHelper.getUserDisplayPhoto(recent.getContactId())))
{
imgHead.loadAvatar("",UserInfoHelper.getUserDisplayPhoto(recent.getContactId()));
}
else
{
imgHead.loadBuddyAvatar(recent.getContactId());
}
} else if (recent.getSessionType() == SessionTypeEnum.Team) {
Team team = NimUIKit.getTeamProvider().getTeamById(recent.getContactId());
imgHead.loadTeamIconByTeam(team);
} else if (recent.getSessionType() == SessionTypeEnum.SUPER_TEAM) {
SuperTeam team = NimUIKit.getSuperTeamProvider().getTeamById(recent.getContactId());
imgHead.loadSuperTeamIconByTeam(team);
} else if (recent.getSessionType() == SessionTypeEnum.Ysf) {
imgHead.setImageResource(com.netease.nim.uikit.R.drawable.nim_ic_ysf_default_icon);
}
}
private void updateNewIndicator(RecentContact recent) {
int unreadNum = recent.getUnreadCount();
tvUnread.setVisibility(unreadNum > 0 ? View.VISIBLE : View.GONE);
tvUnread.setText(unreadCountShowRule(unreadNum));
}
private void updateMsgLabel(BaseViewHolder holder, RecentContact recent) {
// 显示消息具体内容
MoonUtil.identifyRecentVHFaceExpressionAndTags(holder.getContext(), tvMessage, getContent(recent), -1, 0.45f);
//tvMessage.setText(getContent());
MsgStatusEnum status = recent.getMsgStatus();
if (status == null) {
imgMsgStatus.setVisibility(View.GONE);
} else {
switch (status) {
case fail:
imgMsgStatus.setImageResource(com.netease.nim.uikit.R.drawable.nim_g_ic_failed_small);
imgMsgStatus.setVisibility(View.VISIBLE);
break;
case sending:
imgMsgStatus.setImageResource(com.netease.nim.uikit.R.drawable.nim_recent_contact_ic_sending);
imgMsgStatus.setVisibility(View.VISIBLE);
break;
default:
imgMsgStatus.setVisibility(View.GONE);
break;
}
}
String timeString = TimeUtil.getTimeShowString(recent.getTime(), true);
tvDatetime.setText(timeString);
}
protected String getOnlineStateContent(RecentContact recent) {
return "";
}
protected void updateOnlineState(RecentContact recent) {
if (recent.getSessionType() == SessionTypeEnum.Team || recent.getSessionType() == SessionTypeEnum.SUPER_TEAM) {
tvOnlineState.setVisibility(View.GONE);
} else {
String onlineStateContent = getOnlineStateContent(recent);
if (TextUtils.isEmpty(onlineStateContent)) {
tvOnlineState.setVisibility(View.GONE);
} else {
tvOnlineState.setVisibility(View.VISIBLE);
tvOnlineState.setText(getOnlineStateContent(recent));
}
}
}
protected void updateNickLabel(String nick) {
if (labelWidth == null) {
labelWidth = ScreenUtil.screenWidth - ScreenUtil.dip2px(120); // 减去固定的头像和时间宽度;
}
if (labelWidth > 0) {
tvNickname.setMaxWidth(labelWidth);
}
tvNickname.setText(nick);
}
protected String unreadCountShowRule(int unread) {
unread = Math.min(unread, 99);
return String.valueOf(unread);
}
protected RecentContactsCallback getCallback() {
return ((RecentContactAdapter) getAdapter()).getCallback();
}
}
@@ -0,0 +1,955 @@
package cn.shangyu.gdxzExpert.netease.session;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.SystemClock;
import android.text.Editable;
import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.alibaba.fastjson.JSONObject;
import com.github.dfqin.grantor.PermissionListener;
import com.github.dfqin.grantor.PermissionsUtil;
import com.hjq.window.EasyWindow;
import com.netease.nim.uikit.R;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.UIKitOptions;
import com.netease.nim.uikit.api.model.session.SessionCustomization;
import com.netease.nim.uikit.business.ait.AitTextChangeListener;
import com.netease.nim.uikit.business.session.actions.BaseAction;
import com.netease.nim.uikit.business.session.constant.Extras;
import com.netease.nim.uikit.business.session.emoji.EmoticonPickerView;
import com.netease.nim.uikit.business.session.emoji.IEmoticonSelectedListener;
import com.netease.nim.uikit.business.session.emoji.MoonUtil;
import com.netease.nim.uikit.business.session.module.Container;
import com.netease.nim.uikit.business.session.module.input.ActionsPanel;
import com.netease.nim.uikit.business.uinfo.UserInfoHelper;
import com.netease.nim.uikit.common.ToastHelper;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nim.uikit.common.util.string.StringUtil;
import com.netease.nim.uikit.impl.NimUIKitImpl;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.media.record.AudioRecorder;
import com.netease.nimlib.sdk.media.record.IAudioRecordCallback;
import com.netease.nimlib.sdk.media.record.RecordType;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.CustomNotification;
import com.netease.nimlib.sdk.msg.model.CustomNotificationConfig;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import java.io.File;
import java.util.List;
import cn.shangyu.gdxzExpert.netease.ptop.MessageFragment;
/**
* 底部文本编辑,语音等模块
* Created by hzxuwen on 2015/6/16.
*/
public class InputPanel implements IEmoticonSelectedListener, IAudioRecordCallback, AitTextChangeListener {
private static final String TAG = "MsgSendLayout";
private static final int SHOW_LAYOUT_DELAY = 200;
protected Container container;
protected View view;
protected Handler uiHandler;
protected View actionPanelBottomLayout; // 更多布局
protected LinearLayout messageActivityBottomLayout;
public EditText messageEditText;// 文本消息编辑框
protected Button audioRecordBtn; // 录音按钮
protected View audioAnimLayout; // 录音动画布局
protected FrameLayout textAudioSwitchLayout; // 切换文本,语音按钮布局
protected View switchToTextButtonInInputBar;// 文本消息选择按钮
protected View switchToAudioButtonInInputBar;// 语音消息选择按钮
protected View moreFuntionButtonInInputBar;// 更多消息选择按钮
protected View sendMessageButtonInInputBar;// 发送消息按钮
protected View emojiButtonInInputBar;// emoji选择按钮
protected View messageInputBar;
protected TextView replyInfoTv;// 被回复消息信息
protected View replyLayout;
protected ImageView cancelReplyImg;// 取消回复消息的按钮
private SessionCustomization customization;
// 表情
protected EmoticonPickerView emoticonPickerView; // 贴图表情控件
// 语音
protected AudioRecorder audioMessageHelper;
private Chronometer time;
private TextView timerTip;
private LinearLayout timerTipContainer;
private boolean started = false;
private boolean cancelled = false;
private boolean touched = false; // 是否按着
private boolean isKeyboardShowed = true; // 是否显示键盘
// state
private boolean actionPanelBottomLayoutHasSetup = false;
private boolean isTextAudioSwitchShow = true;
// adapter
private List<BaseAction> actions;
// data
private long typingTime = 0;
private boolean isRobotSession;
private TextWatcher aitTextWatcher;
private IMMessage replyMessage = null;
public InputPanel(Container container, View view, List<BaseAction> actions, boolean isTextAudioSwitchShow) {
this.container = container;
this.view = view;
this.actions = actions;
this.uiHandler = new Handler();
this.isTextAudioSwitchShow = isTextAudioSwitchShow;
init();
}
public InputPanel(Container container, View view, List<BaseAction> actions) {
this(container, view, actions, true);
}
public void onPause() {
// 停止录音
if (audioMessageHelper != null) {
onEndAudioRecord(true);
}
}
public void onDestroy() {
// release
if (audioMessageHelper != null) {
audioMessageHelper.destroyAudioRecorder();
}
}
public boolean collapse(boolean immediately) {
boolean respond = (emoticonPickerView != null && emoticonPickerView.getVisibility() == View.VISIBLE
|| actionPanelBottomLayout != null && actionPanelBottomLayout.getVisibility() == View.VISIBLE);
hideAllInputLayout(immediately);
return respond;
}
public void addAitTextWatcher(TextWatcher watcher) {
aitTextWatcher = watcher;
}
private void init() {
initViews();
initInputBarListener();
initTextEdit();
initAudioRecordButton();
restoreText(false);
for (int i = 0; i < actions.size(); ++i) {
actions.get(i).setIndex(i);
actions.get(i).setContainer(container);
}
}
public IMMessage getReplyMessage() {
return replyMessage;
}
public void setReplyMessage(IMMessage replyMessage) {
this.replyMessage = replyMessage;
refreshReplyMsgLayout();
}
public void resetReplyMessage() {
setReplyMessage(null);
}
public void setCustomization(SessionCustomization customization) {
this.customization = customization;
if (customization != null) {
emoticonPickerView.setWithSticker(customization.withSticker);
}
}
public void reload(Container container, SessionCustomization customization) {
this.container = container;
setCustomization(customization);
}
private void initViews() {
// input bar
messageActivityBottomLayout = view.findViewById(R.id.messageActivityBottomLayout);
messageInputBar = view.findViewById(R.id.textMessageLayout);
switchToTextButtonInInputBar = view.findViewById(R.id.buttonTextMessage);
switchToAudioButtonInInputBar = view.findViewById(R.id.buttonAudioMessage);
moreFuntionButtonInInputBar = view.findViewById(R.id.buttonMoreFuntionInText);
emojiButtonInInputBar = view.findViewById(R.id.emoji_button);
sendMessageButtonInInputBar = view.findViewById(R.id.buttonSendMessage);
messageEditText = view.findViewById(R.id.editTextMessage);
replyInfoTv = view.findViewById(R.id.tvReplyInfo);
replyLayout = view.findViewById(R.id.layout_reply);
cancelReplyImg = view.findViewById(R.id.imgCancelReply);
// 语音
audioRecordBtn = view.findViewById(R.id.audioRecord);
audioAnimLayout = view.findViewById(R.id.layoutPlayAudio);
time = view.findViewById(R.id.timer);
timerTip = view.findViewById(R.id.timer_tip);
timerTipContainer = view.findViewById(R.id.timer_tip_container);
// 表情
emoticonPickerView = view.findViewById(R.id.emoticon_picker_view);
// 显示录音按钮
switchToTextButtonInInputBar.setVisibility(View.GONE);
switchToAudioButtonInInputBar.setVisibility(View.VISIBLE);
// 文本录音按钮切换布局
textAudioSwitchLayout = view.findViewById(R.id.switchLayout);
if (isTextAudioSwitchShow) {
textAudioSwitchLayout.setVisibility(View.VISIBLE);
} else {
textAudioSwitchLayout.setVisibility(View.GONE);
}
}
private void initInputBarListener() {
switchToTextButtonInInputBar.setOnClickListener(clickListener);
switchToAudioButtonInInputBar.setOnClickListener(clickListener);
emojiButtonInInputBar.setOnClickListener(clickListener);
sendMessageButtonInInputBar.setOnClickListener(clickListener);
moreFuntionButtonInInputBar.setOnClickListener(clickListener);
cancelReplyImg.setOnClickListener(clickListener);
}
private void initTextEdit() {
RecentContact recent= NIMClient.getService(MsgService.class).queryRecentContact(container.account, container.sessionType);
if(recent!=null)
{
if(recent.getExtension()!=null&&recent.getExtension().get(Extras.CAO_GAO)!=null
&& !TextUtils.isEmpty(recent.getExtension().get(Extras.CAO_GAO).toString()) && !"".equalsIgnoreCase(recent.getExtension().get(Extras.CAO_GAO).toString())
&& !"null".equalsIgnoreCase(recent.getExtension().get(Extras.CAO_GAO).toString()))
{
messageEditText.setText(recent.getExtension().get(Extras.CAO_GAO).toString());
}
}
messageEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE);
messageEditText.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
switchToTextLayout(true);
}
return false;
}
});
messageEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
// messageEditText.setHint("");
checkSendButtonEnable(messageEditText);
}
});
messageEditText.addTextChangedListener(new TextWatcher() {
private int start;
private int count;
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
this.start = start;
this.count = count;
if (aitTextWatcher != null) {
aitTextWatcher.onTextChanged(s, start, before, count);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (aitTextWatcher != null) {
aitTextWatcher.beforeTextChanged(s, start, count, after);
}
}
@Override
public void afterTextChanged(Editable s) {
checkSendButtonEnable(messageEditText);
MoonUtil.replaceEmoticons(container.activity, s, start, count);
int editEnd = messageEditText.getSelectionEnd();
messageEditText.removeTextChangedListener(this);
while (StringUtil.counterChars(s.toString()) > NimUIKitImpl.getOptions().maxInputTextLength && editEnd > 0) {
s.delete(editEnd - 1, editEnd);
editEnd--;
}
messageEditText.setSelection(editEnd);
messageEditText.addTextChangedListener(this);
if (aitTextWatcher != null) {
aitTextWatcher.afterTextChanged(s);
}
sendTypingCommand();
}
});
}
/**
* 发送“正在输入”通知
*/
private void sendTypingCommand() {
if (container.account.equals(NimUIKit.getAccount())) {
return;
}
if (container.sessionType == SessionTypeEnum.Team || container.sessionType == SessionTypeEnum.ChatRoom) {
return;
}
if (System.currentTimeMillis() - typingTime > 5000L) {
typingTime = System.currentTimeMillis();
CustomNotification command = new CustomNotification();
command.setSessionId(container.account);
command.setSessionType(container.sessionType);
CustomNotificationConfig config = new CustomNotificationConfig();
config.enablePush = false;
config.enableUnreadCount = false;
command.setConfig(config);
JSONObject json = new JSONObject();
json.put("id", "1");
command.setContent(json.toString());
NIMClient.getService(MsgService.class).sendCustomNotification(command);
}
}
/**
* ************************* 键盘布局切换 *******************************
*/
private View.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v == switchToTextButtonInInputBar) {
switchToTextLayout(true);// 显示文本发送的布局
} else if (v == sendMessageButtonInInputBar) {
onTextMessageSendButtonPressed();
} else if (v == switchToAudioButtonInInputBar) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (PermissionsUtil.hasPermission(container.activity, Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//有访问录音
switchToAudioLayout();
} else {
EasyWindow.with(container.activity).setGravity(Gravity.TOP).setYOffset(200).setWidth(1000)
.setContentView(cn.shangyu.gdxzExpert.R.layout.float_top_dialog_record).show();
PermissionsUtil.requestPermission(container.activity, new PermissionListener() {
@Override
public void permissionGranted(@NonNull String[] permissions) {
EasyWindow.cancelAll();
//用户授予了访问录音的权限
switchToAudioLayout();
}
@Override
public void permissionDenied(@NonNull String[] permissions) {
EasyWindow.cancelAll();
//用户拒绝了访问录音的申请
}
}, new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE});
}
}
} else if (v == moreFuntionButtonInInputBar) {
toggleActionPanelLayout();
} else if (v == emojiButtonInInputBar) {
toggleEmojiLayout();
} else if (v == cancelReplyImg) {
cancelReply();
}
}
};
// 点击edittext,切换键盘和更多布局
private void switchToTextLayout(boolean needShowInput) {
hideEmojiLayout();
hideActionPanelLayout();
audioRecordBtn.setVisibility(View.GONE);
messageEditText.setVisibility(View.VISIBLE);
switchToTextButtonInInputBar.setVisibility(View.GONE);
switchToAudioButtonInInputBar.setVisibility(View.VISIBLE);
messageInputBar.setVisibility(View.VISIBLE);
if (needShowInput) {
uiHandler.postDelayed(showTextRunnable, SHOW_LAYOUT_DELAY);
} else {
hideInputMethod();
}
}
// 发送文本消息
private void onTextMessageSendButtonPressed() {
String text = messageEditText.getText().toString();
IMMessage textMessage = createTextMessage(text);
textMessage.setRemoteExtension(MessageFragment.ext);
if (container.proxy.sendMessage(textMessage)) {
restoreText(true);
}
}
protected IMMessage createTextMessage(String text) {
return MessageBuilder.createTextMessage(container.account, container.sessionType, text);
}
// 切换成音频,收起键盘,按钮切换成键盘
private void switchToAudioLayout() {
messageEditText.setVisibility(View.GONE);
audioRecordBtn.setVisibility(View.VISIBLE);
hideInputMethod();
hideEmojiLayout();
hideActionPanelLayout();
switchToAudioButtonInInputBar.setVisibility(View.GONE);
switchToTextButtonInInputBar.setVisibility(View.VISIBLE);
}
// 点击“+”号按钮,切换更多布局和键盘
private void toggleActionPanelLayout() {
audioRecordBtn.setVisibility(View.GONE);
messageEditText.setVisibility(View.VISIBLE);
switchToTextButtonInInputBar.setVisibility(View.GONE);
switchToAudioButtonInInputBar.setVisibility(View.VISIBLE);
messageInputBar.setVisibility(View.VISIBLE);
if (actionPanelBottomLayout == null || actionPanelBottomLayout.getVisibility() == View.GONE) {
showActionPanelLayout();
} else {
hideActionPanelLayout();
}
}
// 点击表情,切换到表情布局
private void toggleEmojiLayout() {
if (emoticonPickerView == null || emoticonPickerView.getVisibility() == View.GONE) {
showEmojiLayout();
} else {
hideEmojiLayout();
}
}
private void cancelReply() {
resetReplyMessage();
}
// 隐藏表情布局
private void hideEmojiLayout() {
uiHandler.removeCallbacks(showEmojiRunnable);
if (emoticonPickerView != null) {
emoticonPickerView.setVisibility(View.GONE);
}
}
// 隐藏更多布局
private void hideActionPanelLayout() {
uiHandler.removeCallbacks(showMoreFuncRunnable);
if (actionPanelBottomLayout != null) {
actionPanelBottomLayout.setVisibility(View.GONE);
}
}
// 隐藏键盘布局
private void hideInputMethod() {
isKeyboardShowed = false;
uiHandler.removeCallbacks(showTextRunnable);
InputMethodManager imm = (InputMethodManager) container.activity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(messageEditText.getWindowToken(), 0);
messageEditText.clearFocus();
}
// 隐藏语音布局
private void hideAudioLayout() {
audioRecordBtn.setVisibility(View.GONE);
messageEditText.setVisibility(View.VISIBLE);
switchToTextButtonInInputBar.setVisibility(View.VISIBLE);
switchToAudioButtonInInputBar.setVisibility(View.GONE);
}
// 显示表情布局
private void showEmojiLayout() {
hideInputMethod();
hideActionPanelLayout();
// hideAudioLayout();
audioRecordBtn.setVisibility(View.GONE);
messageEditText.setVisibility(View.VISIBLE);
switchToTextButtonInInputBar.setVisibility(View.GONE);
switchToAudioButtonInInputBar.setVisibility(View.VISIBLE);
messageInputBar.setVisibility(View.VISIBLE);
messageEditText.requestFocus();
uiHandler.postDelayed(showEmojiRunnable, 200);
emoticonPickerView.setVisibility(View.VISIBLE);
emoticonPickerView.show(this);
container.proxy.onInputPanelExpand();
}
// 初始化更多布局
private void addActionPanelLayout() {
if (actionPanelBottomLayout == null) {
View.inflate(container.activity, R.layout.nim_message_activity_actions_layout, messageActivityBottomLayout);
actionPanelBottomLayout = view.findViewById(R.id.actionsLayout);
actionPanelBottomLayoutHasSetup = false;
}
initActionPanelLayout();
}
// 显示键盘布局
private void showInputMethod(EditText editTextMessage) {
editTextMessage.requestFocus();
//如果已经显示,则继续操作时不需要把光标定位到最后
if (!isKeyboardShowed) {
editTextMessage.setSelection(editTextMessage.getText().length());
isKeyboardShowed = true;
}
InputMethodManager imm = (InputMethodManager) container.activity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(editTextMessage, 0);
container.proxy.onInputPanelExpand();
}
// 显示更多布局
private void showActionPanelLayout() {
addActionPanelLayout();
hideEmojiLayout();
hideInputMethod();
uiHandler.postDelayed(showMoreFuncRunnable, SHOW_LAYOUT_DELAY);
container.proxy.onInputPanelExpand();
}
// 显示回复消息信息
private void refreshReplyMsgLayout() {
if (replyMessage == null) {
replyLayout.setVisibility(View.GONE);
return;
}
uiHandler.postDelayed(showTextRunnable, SHOW_LAYOUT_DELAY);
String fromDisplayName = UserInfoHelper.getUserDisplayNameInSession(replyMessage.getFromAccount(), replyMessage.getSessionType(), replyMessage.getSessionId());
String content = customization.getMessageDigest(replyMessage);
String text = String.format(container.activity.getString(R.string.reply_with_message), fromDisplayName, content);
replyInfoTv.setText(text);
replyLayout.setVisibility(View.VISIBLE);
}
// 初始化具体more layout中的项目
private void initActionPanelLayout() {
if (actionPanelBottomLayoutHasSetup) {
return;
}
ActionsPanel.init(view, actions);
actionPanelBottomLayoutHasSetup = true;
}
private Runnable showEmojiRunnable = new Runnable() {
@Override
public void run() {
emoticonPickerView.setVisibility(View.VISIBLE);
}
};
private Runnable showMoreFuncRunnable = new Runnable() {
@Override
public void run() {
actionPanelBottomLayout.setVisibility(View.VISIBLE);
}
};
private Runnable showTextRunnable = new Runnable() {
@Override
public void run() {
showInputMethod(messageEditText);
}
};
private void restoreText(boolean clearText) {
if (clearText) {
messageEditText.setText("");
}
checkSendButtonEnable(messageEditText);
}
/**
* 显示发送或更多
*
* @param editText
*/
private void checkSendButtonEnable(EditText editText) {
if (isRobotSession) {
return;
}
String textMessage = editText.getText().toString();
if (!TextUtils.isEmpty(StringUtil.removeBlanks(textMessage)) && editText.hasFocus()) {
moreFuntionButtonInInputBar.setVisibility(View.GONE);
sendMessageButtonInInputBar.setVisibility(View.VISIBLE);
} else {
sendMessageButtonInInputBar.setVisibility(View.GONE);
moreFuntionButtonInInputBar.setVisibility(View.VISIBLE);
}
}
/**
* *************** IEmojiSelectedListener ***************
*/
@Override
public void onEmojiSelected(String key) {
Editable mEditable = messageEditText.getText();
if (key.equals("/DEL")) {
messageEditText.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
} else {
int start = messageEditText.getSelectionStart();
int end = messageEditText.getSelectionEnd();
start = (start < 0 ? 0 : start);
end = (start < 0 ? 0 : end);
mEditable.replace(start, end, key);
}
}
private Runnable hideAllInputLayoutRunnable;
@Override
public void onStickerSelected(String category, String item) {
Log.i("InputPanel", "onStickerSelected, category =" + category + ", sticker =" + item);
if (customization != null) {
MsgAttachment attachment = customization.createStickerAttachment(category, item);
IMMessage stickerMessage = MessageBuilder.createCustomMessage(container.account, container.sessionType, "贴图消息", attachment);
container.proxy.sendMessage(stickerMessage);
}
}
@Override
public void onTextAdd(String content, int start, int length) {
if (messageEditText.getVisibility() != View.VISIBLE ||
(emoticonPickerView != null && emoticonPickerView.getVisibility() == View.VISIBLE)) {
switchToTextLayout(true);
} else {
uiHandler.postDelayed(showTextRunnable, SHOW_LAYOUT_DELAY);
}
messageEditText.getEditableText().insert(start, content);
}
@Override
public void onTextDelete(int start, int length) {
if (messageEditText.getVisibility() != View.VISIBLE) {
switchToTextLayout(true);
} else {
uiHandler.postDelayed(showTextRunnable, SHOW_LAYOUT_DELAY);
}
int end = start + length - 1;
messageEditText.getEditableText().replace(start, end, "");
}
public int getEditSelectionStart() {
return messageEditText.getSelectionStart();
}
/**
* 隐藏所有输入布局
*/
private void hideAllInputLayout(boolean immediately) {
if (hideAllInputLayoutRunnable == null) {
hideAllInputLayoutRunnable = new Runnable() {
@Override
public void run() {
hideInputMethod();
hideActionPanelLayout();
hideEmojiLayout();
}
};
}
long delay = immediately ? 0 : ViewConfiguration.getDoubleTapTimeout();
uiHandler.postDelayed(hideAllInputLayoutRunnable, delay);
}
/**
* ****************************** 语音 ***********************************
*/
private void initAudioRecordButton() {
audioRecordBtn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
touched = true;
initAudioRecord();
onStartAudioRecord();
} else if (event.getAction() == MotionEvent.ACTION_CANCEL
|| event.getAction() == MotionEvent.ACTION_UP) {
touched = false;
onEndAudioRecord(isCancelled(v, event));
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
touched = true;
cancelAudioRecord(isCancelled(v, event));
}
return false;
}
});
}
// 上滑取消录音判断
private static boolean isCancelled(View view, MotionEvent event) {
int[] location = new int[2];
view.getLocationOnScreen(location);
if (event.getRawX() < location[0] || event.getRawX() > location[0] + view.getWidth()
|| event.getRawY() < location[1] - 40) {
return true;
}
return false;
}
/**
* 初始化AudioRecord
*/
private void initAudioRecord() {
if (audioMessageHelper == null) {
UIKitOptions options = NimUIKitImpl.getOptions();
audioMessageHelper = new AudioRecorder(container.activity, options.audioRecordType, options.audioRecordMaxTime, this);
}
}
/**
* 开始语音录制
*/
private void onStartAudioRecord() {
container.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
audioMessageHelper.startRecord();
cancelled = false;
}
/**
* 结束语音录制
*
* @param cancel
*/
private void onEndAudioRecord(boolean cancel) {
started = false;
container.activity.getWindow().setFlags(0, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
audioMessageHelper.completeRecord(cancel);
audioRecordBtn.setText(R.string.record_audio);
audioRecordBtn.setBackgroundResource(R.drawable.nim_message_input_edittext_box);
stopAudioRecordAnim();
}
/**
* 取消语音录制
*
* @param cancel
*/
private void cancelAudioRecord(boolean cancel) {
// reject
if (!started) {
return;
}
// no change
if (cancelled == cancel) {
return;
}
cancelled = cancel;
updateTimerTip(cancel);
}
/**
* 正在进行语音录制和取消语音录制,界面展示
*
* @param cancel
*/
private void updateTimerTip(boolean cancel) {
if (cancel) {
timerTip.setText(R.string.recording_cancel_tip);
timerTipContainer.setBackgroundResource(R.drawable.nim_cancel_record_red_bg);
} else {
timerTip.setText(R.string.recording_cancel);
timerTipContainer.setBackgroundResource(0);
}
}
/**
* 开始语音录制动画
*/
private void playAudioRecordAnim() {
audioAnimLayout.setVisibility(View.VISIBLE);
time.setBase(SystemClock.elapsedRealtime());
time.start();
}
/**
* 结束语音录制动画
*/
private void stopAudioRecordAnim() {
audioAnimLayout.setVisibility(View.GONE);
time.stop();
time.setBase(SystemClock.elapsedRealtime());
}
// 录音状态回调
@Override
public void onRecordReady() {
}
@Override
public void onRecordStart(File audioFile, RecordType recordType) {
started = true;
if (!touched) {
return;
}
audioRecordBtn.setText(R.string.record_audio_end);
audioRecordBtn.setBackgroundResource(R.drawable.nim_message_input_edittext_box);
updateTimerTip(false); // 初始化语音动画状态
playAudioRecordAnim();
}
@Override
public void onRecordSuccess(File audioFile, long audioLength, RecordType recordType) {
IMMessage audioMessage = MessageBuilder.createAudioMessage(container.account, container.sessionType, audioFile, audioLength);
container.proxy.sendMessage(audioMessage);
}
@Override
public void onRecordFail() {
if (started) {
ToastHelper.showToast(container.activity, R.string.recording_error);
}
}
@Override
public void onRecordCancel() {
}
@Override
public void onRecordReachedMaxTime(final int maxTime) {
stopAudioRecordAnim();
// EasyAlertDialogHelper.createOkCancelDiolag(container.activity, "", container.activity.getString(R.string.recording_max_time), false, new EasyAlertDialogHelper.OnDialogActionListener() {
// @Override
// public void doCancelAction() {
// }
//
// @Override
// public void doOkAction() {
audioMessageHelper.handleEndRecord(true, maxTime);
// }
// }).show();
}
public boolean isRecording() {
return audioMessageHelper != null && audioMessageHelper.isRecording();
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 69) {
if (data!=null&&!StringUtil.isEmpty(data.getStringExtra("message"))) {
String mess = data.getStringExtra("message");
messageEditText.setText(mess);// 聊天输入框
moreFuntionButtonInInputBar.setVisibility(View.GONE);
sendMessageButtonInInputBar.setVisibility(View.VISIBLE);
}
}
if (resultCode != Activity.RESULT_OK) {
return;
}
int index = (requestCode << 16) >> 24;
if (index != 0) {
index--;
if (index < 0 | index >= actions.size()) {
LogUtil.d(TAG, "request code out of actions' range");
return;
}
BaseAction action = actions.get(index);
if (action != null) {
action.onActivityResult(requestCode & 0xff, resultCode, data);
}
}
}
public void switchRobotMode(boolean isRobot) {
isRobotSession = isRobot;
if (isRobot) {
textAudioSwitchLayout.setVisibility(View.GONE);
emojiButtonInInputBar.setVisibility(View.GONE);
sendMessageButtonInInputBar.setVisibility(View.VISIBLE);
moreFuntionButtonInInputBar.setVisibility(View.GONE);
} else {
textAudioSwitchLayout.setVisibility(View.VISIBLE);
emojiButtonInInputBar.setVisibility(View.VISIBLE);
sendMessageButtonInInputBar.setVisibility(View.GONE);
moreFuntionButtonInInputBar.setVisibility(View.VISIBLE);
}
}
}
@@ -0,0 +1,786 @@
package cn.shangyu.gdxzExpert.netease.session;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.text.TextUtils;
import android.view.View;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.model.CreateMessageCallback;
import com.netease.nim.uikit.api.model.recent.RecentCustomization;
import com.netease.nim.uikit.api.model.session.SessionCustomization;
import com.netease.nim.uikit.api.wrapper.NimMessageRevokeObserver;
import com.netease.nim.uikit.business.session.actions.BaseAction;
import com.netease.nim.uikit.business.session.helper.MessageListPanelHelper;
import com.netease.nim.uikit.business.session.helper.TeamNotificationHelper;
import com.netease.nim.uikit.business.session.module.IMultiRetweetMsgCreator;
import com.netease.nim.uikit.business.session.module.MsgForwardFilter;
import com.netease.nim.uikit.business.session.module.MsgRevokeFilter;
import com.netease.nim.uikit.business.session.viewholder.MsgViewHolderUnknown;
import com.netease.nim.uikit.business.team.model.TeamExtras;
import com.netease.nim.uikit.business.team.model.TeamRequestCode;
import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog;
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper;
import com.netease.nim.uikit.common.ui.popupmenu.NIMPopupMenu;
import com.netease.nim.uikit.common.ui.popupmenu.PopupMenuItem;
import com.netease.nim.uikit.impl.cache.TeamDataCache;
import com.netease.nim.uikit.impl.customization.DefaultRecentCustomization;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.attachment.ImageAttachment;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.attachment.NotificationAttachment;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.LocalAntiSpamResult;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.robot.model.RobotAttachment;
import com.netease.nimlib.sdk.team.constant.TeamTypeEnum;
import com.netease.nimlib.sdk.team.model.Team;
import java.util.ArrayList;
import java.util.List;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.DemoCache;
import cn.shangyu.gdxzExpert.netease.activity.MessageInfoActivity;
import cn.shangyu.gdxzExpert.netease.ptop.P2PMessageActivity;
import cn.shangyu.gdxzExpert.netease.session.action.EasyAction;
import cn.shangyu.gdxzExpert.netease.session.action.HospitalAction;
import cn.shangyu.gdxzExpert.netease.session.action.ShoppingAction;
import cn.shangyu.gdxzExpert.netease.session.action.TeachAction;
import cn.shangyu.gdxzExpert.netease.session.action.VisitAction;
import cn.shangyu.gdxzExpert.netease.session.extension.CustomAttachParser;
import cn.shangyu.gdxzExpert.netease.session.extension.RedPacketAttachment;
import cn.shangyu.gdxzExpert.netease.session.extension.RedPacketOpenedAttachment;
import cn.shangyu.gdxzExpert.netease.session.extension.TeachAttachment;
import cn.shangyu.gdxzExpert.netease.session.viewholder.MsgViewHolderPicture;
import cn.shangyu.gdxzExpert.netease.session.viewholder.MsgViewHolderTeach;
import cn.shangyu.gdxzExpert.netease.session.viewholder.MsgViewHolderTip;
import cn.shangyu.gdxzExpert.utils.StringUtil;
/**
* UIKit自定义消息界面用法展示类
*/
public class SessionHelper {
private static final int ACTION_HISTORY_QUERY_PERSIST_CLEAR = 0;
private static final int ACTION_HISTORY_QUERY_NOT_PERSIST_CLEAR = 1;
private static final int ACTION_SEARCH_MESSAGE = 2;
private static final int ACTION_CLEAR_MESSAGE_RECORD = 3;
private static final int ACTION_CLEAR_MESSAGE_NOT_RECORD = 4;
private static final int ACTION_CLEAR_MESSAGE = 5;
private static SessionCustomization p2pCustomization;
private static SessionCustomization normalTeamCustomization;
private static SessionCustomization advancedTeamCustomization;
private static SessionCustomization myP2pCustomization;
private static SessionCustomization robotCustomization;
private static RecentCustomization recentCustomization;
private static NIMPopupMenu popupMenu;
private static List<PopupMenuItem> menuItemList;
public static final boolean USE_LOCAL_ANTISPAM = true;
public static void init() {
// 注册自定义消息附件解析器
NIMClient.getService(MsgService.class).registerCustomAttachmentParser(new CustomAttachParser());
// 注册各种扩展消息类型的显示ViewHolder
registerViewHolders();
// 设置会话中点击事件响应处理
// setSessionListener();
// 注册消息转发过滤器
registerMsgForwardFilter();
// 注册消息撤回过滤器
registerMsgRevokeFilter();
// 注册消息撤回监听器
registerMsgRevokeObserver();
NimUIKit.setCommonP2PSessionCustomization(getP2pCustomization());
NimUIKit.setCommonTeamSessionCustomization(getTeamCustomization(null));
NimUIKit.setRecentCustomization(getRecentCustomization());
}
public static void startP2PSession(Context context, String account,String gdxz_sessionType,String state) {
startP2PSession(context, account, null,gdxz_sessionType,state);
}
public static void startP2PSessionname(Context context, String account,String gdxz_sessionType,String state,String name) {
if (!StringUtil.isEmpty(DemoCache.getAccount())&&!DemoCache.getAccount().equals(account)) {
if (NimUIKit.getRobotInfoProvider().getRobotByAccount(account) != null) {
NimUIKit.startChatting(context, account, SessionTypeEnum.P2P, getRobotCustomization(), null);
} else {
P2PMessageActivity.start(context, account, null, null,gdxz_sessionType,state,name);
}
} else {
NimUIKit.startChatting(context, account, SessionTypeEnum.P2P, getMyP2pCustomization(), null);
}
}
public static void startP2PSession(Context context, String account, IMMessage anchor,String gdxz_sessionType,String state) {
if (!StringUtil.isEmpty(DemoCache.getAccount())&&!DemoCache.getAccount().equals(account)) {
if (NimUIKit.getRobotInfoProvider().getRobotByAccount(account) != null) {
NimUIKit.startChatting(context, account, SessionTypeEnum.P2P, getRobotCustomization(), anchor);
} else {
P2PMessageActivity.start(context, account, null, anchor,gdxz_sessionType,state);
// NimUIKit.startP2PSession(context, account, anchor);
}
} else {
NimUIKit.startChatting(context, account, SessionTypeEnum.P2P, getMyP2pCustomization(), anchor);
}
}
public static void startTeamSession(Context context, String tid) {
startTeamSession(context, tid, null);
}
public static void startTeamSession(Context context, String tid, IMMessage anchor) {
NimUIKit.startTeamSession(context, tid, getTeamCustomization(tid), anchor);
}
// 打开群聊界面(用于 UIKIT 中部分界面跳转回到指定的页面)
public static void startTeamSession(Context context, String tid, Class<? extends Activity> backToClass,
IMMessage anchor) {
NimUIKit.startChatting(context, tid, SessionTypeEnum.Team, getTeamCustomization(tid), backToClass, anchor);
}
// 定制化单聊界面。如果使用默认界面,返回null即可
private static SessionCustomization getP2pCustomization() {
if (p2pCustomization == null) {
p2pCustomization = new SessionCustomization() {
// 由于需要Activity Result, 所以重载该函数。
@Override
public void onActivityResult(final Activity activity, int requestCode, int resultCode, Intent data) {
super.onActivityResult(activity, requestCode, resultCode, data);
}
@Override
public boolean isAllowSendMessage(IMMessage message) {
return checkLocalAntiSpam(message);
}
@Override
public MsgAttachment createStickerAttachment(String category, String item) {
// return new StickerAttachment(category, item);
return null;
}
@Override
public String getMessageDigest(IMMessage message) {
return getMsgDigest(message);
}
};
// 背景
// p2pCustomization.backgroundColor = Color.BLUE;
// p2pCustomization.backgroundUri = "file:///android_asset/xx/bk.jpg";
// p2pCustomization.backgroundUri = "file:///sdcard/Pictures/bk.png";
// p2pCustomization.backgroundUri = "android.resource://com.netease.nim.demo/drawable/bk"
// 定制加号点开后可以包含的操作, 默认已经有图片,视频等消息了
ArrayList<BaseAction> actions = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// actions.add(new AVChatAction(AVChatType.AUDIO));
// actions.add(new AVChatAction(AVChatType.VIDEO));
}
// actions.add(new RTSAction());
// actions.add(new SnapChatAction());
// actions.add(new GuessAction());
// actions.add(new FileAction());
// actions.add(new TipAction());
// if (NIMRedPacketClient.isEnable()) {
// actions.add(new RedPacketAction());
// }
actions.add(new EasyAction());
actions.add(new TeachAction());
actions.add(new VisitAction());
actions.add(new ShoppingAction());
if(cn.shangyu.gdxzExpert.utils.CommonUtil.showHospital())
{
actions.add(new HospitalAction());
}
p2pCustomization.actions = actions;
p2pCustomization.withSticker = true;
// 定制ActionBar右边的按钮,可以加多个
ArrayList<SessionCustomization.OptionsButton> buttons = new ArrayList<>();
SessionCustomization.OptionsButton cloudMsgButton = new SessionCustomization.OptionsButton() {
@Override
public void onClick(Context context, View view, String sessionId) {
initPopuptWindow(context, view, sessionId, SessionTypeEnum.P2P);
}
};
cloudMsgButton.iconId = R.drawable.nim_ic_messge_history;
SessionCustomization.OptionsButton infoButton = new SessionCustomization.OptionsButton() {
@Override
public void onClick(Context context, View view, String sessionId) {
MessageInfoActivity.startActivity(context, sessionId); //打开聊天信息
}
};
infoButton.iconId = R.drawable.nim_ic_message_actionbar_p2p_add;
buttons.add(cloudMsgButton);
buttons.add(infoButton);
p2pCustomization.buttons = buttons;
}
return p2pCustomization;
}
private static SessionCustomization getMyP2pCustomization() {
if (myP2pCustomization == null) {
myP2pCustomization = new SessionCustomization() {
// 由于需要Activity Result, 所以重载该函数。
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
if (requestCode == TeamRequestCode.REQUEST_CODE && resultCode == Activity.RESULT_OK) {
String result = data.getStringExtra(TeamExtras.RESULT_EXTRA_REASON);
if (result == null) {
return;
}
if (result.equals(TeamExtras.RESULT_EXTRA_REASON_CREATE)) {
String tid = data.getStringExtra(TeamExtras.RESULT_EXTRA_DATA);
if (TextUtils.isEmpty(tid)) {
return;
}
startTeamSession(activity, tid);
activity.finish();
}
}
}
@Override
public boolean isAllowSendMessage(IMMessage message) {
return checkLocalAntiSpam(message);
}
@Override
public MsgAttachment createStickerAttachment(String category, String item) {
// return new StickerAttachment(category, item);
return null;
}
@Override
public String getMessageDigest(IMMessage message) {
return getMsgDigest(message);
}
};
// 定制加号点开后可以包含的操作, 默认已经有图片,视频等消息了
ArrayList<BaseAction> actions = new ArrayList<>();
// actions.add(new SnapChatAction());
// actions.add(new GuessAction());
// actions.add(new FileAction());
myP2pCustomization.actions = actions;
myP2pCustomization.withSticker = true;
// 定制ActionBar右边的按钮,可以加多个
ArrayList<SessionCustomization.OptionsButton> buttons = new ArrayList<>();
SessionCustomization.OptionsButton cloudMsgButton = new SessionCustomization.OptionsButton() {
@Override
public void onClick(Context context, View view, String sessionId) {
initPopuptWindow(context, view, sessionId, SessionTypeEnum.P2P);
}
};
cloudMsgButton.iconId = R.drawable.nim_ic_messge_history;
buttons.add(cloudMsgButton);
myP2pCustomization.buttons = buttons;
}
return myP2pCustomization;
}
private static boolean checkLocalAntiSpam(IMMessage message) {
if (!USE_LOCAL_ANTISPAM) {
return true;
}
LocalAntiSpamResult result = NIMClient.getService(MsgService.class).checkLocalAntiSpam(message.getContent(),
"**");
int operator = result == null ? 0 : result.getOperator();
switch (operator) {
case 1: // 替换,允许发送
message.setContent(result.getContent());
return true;
case 2: // 拦截,不允许发送
return false;
case 3: // 允许发送,交给服务器
message.setClientAntiSpam(true);
return true;
case 0:
default:
break;
}
return true;
}
private static SessionCustomization getRobotCustomization() {
if (robotCustomization == null) {
robotCustomization = new SessionCustomization() {
// 由于需要Activity Result, 所以重载该函数。
@Override
public void onActivityResult(final Activity activity, int requestCode, int resultCode, Intent data) {
super.onActivityResult(activity, requestCode, resultCode, data);
}
@Override
public MsgAttachment createStickerAttachment(String category, String item) {
return null;
}
@Override
public String getMessageDigest(IMMessage message) {
return getMsgDigest(message);
}
};
// 定制ActionBar右边的按钮,可以加多个
ArrayList<SessionCustomization.OptionsButton> buttons = new ArrayList<>();
SessionCustomization.OptionsButton cloudMsgButton = new SessionCustomization.OptionsButton() {
@Override
public void onClick(Context context, View view, String sessionId) {
initPopuptWindow(context, view, sessionId, SessionTypeEnum.P2P);
}
};
cloudMsgButton.iconId = R.drawable.nim_ic_messge_history;
SessionCustomization.OptionsButton infoButton = new SessionCustomization.OptionsButton() {
@Override
public void onClick(Context context, View view, String sessionId) {
// RobotProfileActivity.start(context, sessionId); //打开聊天信息
}
};
infoButton.iconId = R.drawable.nim_ic_actionbar_robot_info;
buttons.add(cloudMsgButton);
buttons.add(infoButton);
robotCustomization.buttons = buttons;
}
return robotCustomization;
}
/**
* 获取消息的简述
*
* @param msg 消息
* @return 简述
*/
private static String getMsgDigest(IMMessage msg) {
switch (msg.getMsgType()) {
case avchat:
MsgAttachment attachment = msg.getAttachment();
// AVChatAttachment avchat = (AVChatAttachment) attachment;
// if (avchat.getState() == AVChatRecordState.Missed && !msg.getFromAccount().equals(
// NimUIKit.getAccount())) {
// // 未接通话请求
// StringBuilder sb = new StringBuilder("[未接");
// if (avchat.getType() == AVChatType.VIDEO) {
// sb.append("视频电话]");
// } else {
// sb.append("音频电话]");
// }
// return sb.toString();
// } else if (avchat.getState() == AVChatRecordState.Success) {
// StringBuilder sb = new StringBuilder();
// if (avchat.getType() == AVChatType.VIDEO) {
// sb.append("[视频电话]: ");
// } else {
// sb.append("[音频电话]: ");
// }
// sb.append(TimeUtil.secToTime(avchat.getDuration()));
// return sb.toString();
// } else {
// if (avchat.getType() == AVChatType.VIDEO) {
// return ("[视频电话]");
// } else {
// return ("[音频电话]");
// }
// }
case text:
case tip:
return msg.getContent();
case image:
return "[图片]";
case video:
return "[视频]";
case audio:
return "[语音消息]";
case location:
return "[位置]";
case file:
return "[文件]";
case notification:
return TeamNotificationHelper.getTeamNotificationText(msg.getSessionId(),
msg.getFromAccount(),
(NotificationAttachment) msg.getAttachment());
case robot:
return "[机器人消息]";
default:
return "[一条新消息] ";
}
}
private static RecentCustomization getRecentCustomization() {
if (recentCustomization == null) {
recentCustomization = new DefaultRecentCustomization() {
@Override
public String getDefaultDigest(RecentContact recent) {
switch (recent.getMsgType()) {
case avchat:
MsgAttachment attachment = recent.getAttachment();
// AVChatAttachment avchat = (AVChatAttachment) attachment;
// if (avchat.getState() == AVChatRecordState.Missed && !recent.getFromAccount().equals(
// NimUIKit.getAccount())) {
// // 未接通话请求
// StringBuilder sb = new StringBuilder("[未接");
// if (avchat.getType() == AVChatType.VIDEO) {
// sb.append("视频电话]");
// } else {
// sb.append("音频电话]");
// }
// return sb.toString();
// } else if (avchat.getState() == AVChatRecordState.Success) {
// StringBuilder sb = new StringBuilder();
// if (avchat.getType() == AVChatType.VIDEO) {
// sb.append("[视频电话]: ");
// } else {
// sb.append("[音频电话]: ");
// }
// sb.append(TimeUtil.secToTime(avchat.getDuration()));
// return sb.toString();
// } else {
// if (avchat.getType() == AVChatType.VIDEO) {
// return ("[视频电话]");
// } else {
// return ("[音频电话]");
// }
// }
}
return super.getDefaultDigest(recent);
}
};
}
return recentCustomization;
}
private static SessionCustomization getTeamCustomization(String tid) {
// if (normalTeamCustomization == null) {
// // 定制加号点开后可以包含的操作, 默认已经有图片,视频等消息了
// final TeamAVChatAction avChatAction = new TeamAVChatAction(AVChatType.VIDEO);
// TeamAVChatProfile.sharedInstance().registerObserver(true);
// ArrayList<BaseAction> actions = new ArrayList<>();
// actions.add(avChatAction);
// actions.add(new GuessAction());
// actions.add(new FileAction());
// if (NIMRedPacketClient.isEnable()) {
// actions.add(new RedPacketAction());
// }
// actions.add(new TipAction());
// SessionTeamCustomization.SessionTeamCustomListener listener = new SessionTeamCustomization.SessionTeamCustomListener() {
//
// @Override
// public void initPopupWindow(Context context, View view, String sessionId,
// SessionTypeEnum sessionTypeEnum) {
// initPopuptWindow(context, view, sessionId, sessionTypeEnum);
// }
//
// @Override
// public void onSelectedAccountsResult(ArrayList<String> selectedAccounts) {
// avChatAction.onSelectedAccountsResult(selectedAccounts);
// }
//
// @Override
// public void onSelectedAccountFail() {
// avChatAction.onSelectedAccountFail();
// }
// };
// normalTeamCustomization = new SessionTeamCustomization(listener) {
//
// @Override
// public boolean isAllowSendMessage(IMMessage message) {
// return checkLocalAntiSpam(message);
// }
//
// @Override
// public String getMessageDigest(IMMessage message) {
// return getMsgDigest(message);
// }
// };
// normalTeamCustomization.actions = actions;
// }
// if (advancedTeamCustomization == null) {
// // 定制加号点开后可以包含的操作, 默认已经有图片,视频等消息了
// final TeamAVChatAction avChatAction = new TeamAVChatAction(AVChatType.VIDEO);
// TeamAVChatProfile.sharedInstance().registerObserver(true);
// ArrayList<BaseAction> actions = new ArrayList<>();
// actions.add(avChatAction);
// actions.add(new GuessAction());
// actions.add(new FileAction());
// actions.add(new AckMessageAction());
// if (NIMRedPacketClient.isEnable()) {
// actions.add(new RedPacketAction());
// }
// actions.add(new TipAction());
// SessionTeamCustomization.SessionTeamCustomListener listener = new SessionTeamCustomization.SessionTeamCustomListener() {
//
// @Override
// public void initPopupWindow(Context context, View view, String sessionId,
// SessionTypeEnum sessionTypeEnum) {
// initPopuptWindow(context, view, sessionId, sessionTypeEnum);
// }
//
//
// @Override
// public void onSelectedAccountsResult(ArrayList<String> selectedAccounts) {
// avChatAction.onSelectedAccountsResult(selectedAccounts);
// }
//
// @Override
// public void onSelectedAccountFail() {
// avChatAction.onSelectedAccountFail();
// }
// };
// advancedTeamCustomization = new SessionTeamCustomization(listener) {
//
// @Override
// public boolean isAllowSendMessage(IMMessage message) {
// return checkLocalAntiSpam(message);
// }
//
// @Override
// public String getMessageDigest(IMMessage message) {
// return getMsgDigest(message);
// }
// };
// advancedTeamCustomization.actions = actions;
// }
if (TextUtils.isEmpty(tid)) {
return normalTeamCustomization;
} else {
Team team = TeamDataCache.getInstance().getTeamById(tid);
if (team != null && team.getType() == TeamTypeEnum.Advanced) {
return advancedTeamCustomization;
}
}
return normalTeamCustomization;
}
private static void registerViewHolders() {
// NimUIKit.registerMsgItemViewHolder(FileAttachment.class, MsgViewHolderFile.class);
// NimUIKit.registerMsgItemViewHolder(AVChatAttachment.class, MsgViewHolderAVChat.class);
// NimUIKit.registerMsgItemViewHolder(GuessAttachment.class, MsgViewHolderGuess.class);
// NimUIKit.registerMsgItemViewHolder(CustomAttachment.class, MsgViewHolderDefCustom.class);
// NimUIKit.registerMsgItemViewHolder(StickerAttachment.class, MsgViewHolderSticker.class);
// NimUIKit.registerMsgItemViewHolder(SnapChatAttachment.class, MsgViewHolderSnapChat.class);
// NimUIKit.registerMsgItemViewHolder(RTSAttachment.class, MsgViewHolderRTS.class);
// NimUIKit.registerMsgItemViewHolder(MultiRetweetAttachment.class, MsgViewHolderMultiRetweet.class);
NimUIKit.registerTipMsgViewHolder(MsgViewHolderTip.class);
NimUIKit.registerMsgItemViewHolder(TeachAttachment.class,MsgViewHolderTeach.class);
NimUIKit.registerMsgItemViewHolder(ImageAttachment.class, MsgViewHolderPicture.class);
registerRedPacketViewHolder();
registerMultiRetweetCreator();
}
private static void registerRedPacketViewHolder() {
// if (NIMRedPacketClient.isEnable()) {
// NimUIKit.registerMsgItemViewHolder(RedPacketAttachment.class, MsgViewHolderRedPacket.class);
// NimUIKit.registerMsgItemViewHolder(RedPacketOpenedAttachment.class, MsgViewHolderOpenRedPacket.class);
// } else {
NimUIKit.registerMsgItemViewHolder(RedPacketAttachment.class, MsgViewHolderUnknown.class);
NimUIKit.registerMsgItemViewHolder(RedPacketOpenedAttachment.class, MsgViewHolderUnknown.class);
// }
}
private static void registerMultiRetweetCreator(){
IMultiRetweetMsgCreator creator = new IMultiRetweetMsgCreator() {
@Override
public void create(List<IMMessage> msgList, boolean shouldEncrypt, CreateMessageCallback callback) {
// MessageHelper.createMultiRetweet(msgList, shouldEncrypt, callback);
}
};
NimUIKit.registerMultiRetweetMsgCreator(creator);
}
/**
* 消息转发过滤器
*/
private static void registerMsgForwardFilter() {
NimUIKit.setMsgForwardFilter(new MsgForwardFilter() {
@Override
public boolean shouldIgnore(IMMessage message) {
if (message.getMsgType() == MsgTypeEnum.custom && message.getAttachment() != null &&
(
// message.getAttachment() instanceof SnapChatAttachment ||
// message.getAttachment() instanceof RTSAttachment ||
message.getAttachment() instanceof RedPacketAttachment)) {
// 白板消息和阅后即焚消息,红包消息 不允许转发
return true;
} else if (message.getMsgType() == MsgTypeEnum.robot && message.getAttachment() != null &&
((RobotAttachment) message.getAttachment()).isRobotSend()) {
return true; // 如果是机器人发送的消息 不支持转发
}
return false;
}
});
}
/**
* 消息撤回过滤器
*/
private static void registerMsgRevokeFilter() {
NimUIKit.setMsgRevokeFilter(new MsgRevokeFilter() {
@Override
public boolean shouldIgnore(IMMessage message) {
// if (message.getAttachment() != null && (message.getAttachment() instanceof AVChatAttachment ||
// message.getAttachment() instanceof RTSAttachment ||
// message.getAttachment() instanceof RedPacketAttachment)) {
// // 视频通话消息和白板消息,红包消息 不允许撤回
// return true;
// } else if (DemoCache.getAccount().equals(message.getSessionId())) {
// // 发给我的电脑 不允许撤回
// return true;
// }
return false;
}
});
}
private static void registerMsgRevokeObserver() {
NIMClient.getService(MsgServiceObserve.class).observeRevokeMessage(new NimMessageRevokeObserver(), true);
}
private static void initPopuptWindow(Context context, View view, String sessionId,
SessionTypeEnum sessionTypeEnum) {
if (popupMenu == null) {
menuItemList = new ArrayList<>();
popupMenu = new NIMPopupMenu(context, menuItemList, listener);
}
menuItemList.clear();
menuItemList.addAll(getMoreMenuItems(context, sessionId, sessionTypeEnum));
popupMenu.notifyData();
popupMenu.show(view);
}
private static NIMPopupMenu.MenuItemClickListener listener = item -> {
final String sessionId = item.getSessionId();
final SessionTypeEnum sessionType = item.getSessionTypeEnum();
final Context context = item.getContext();
switch (item.getTag()) {
case ACTION_HISTORY_QUERY_PERSIST_CLEAR:
// MessageHistoryActivity.start(context, sessionId,
// sessionType, true); // 漫游消息查询,被清除的消息也入库
break;
case ACTION_HISTORY_QUERY_NOT_PERSIST_CLEAR:
// MessageHistoryActivity.start(context, sessionId,
// sessionType, false); // 漫游消息查询,被清除的消息不入库
break;
case ACTION_SEARCH_MESSAGE:
// SearchMessageActivity.start(context, sessionId, sessionType);
break;
case ACTION_CLEAR_MESSAGE_RECORD:
EasyAlertDialogHelper.createOkCancelDiolag(context, null, "确定要清空吗?", true,
new EasyAlertDialogHelper.OnDialogActionListener() {
@Override
public void doCancelAction() {
}
@Override
public void doOkAction() {
NIMClient.getService(MsgService.class)
.clearChattingHistory(
sessionId,
sessionType,
false);
MessageListPanelHelper.getInstance()
.notifyClearMessages(
sessionId);
}
}).show();
break;
case ACTION_CLEAR_MESSAGE_NOT_RECORD:
EasyAlertDialogHelper.createOkCancelDiolag(context, null, "确定要清空吗?", true,
new EasyAlertDialogHelper.OnDialogActionListener() {
@Override
public void doCancelAction() {
}
@Override
public void doOkAction() {
NIMClient.getService(MsgService.class)
.clearChattingHistory(
sessionId,
sessionType,
true);
MessageListPanelHelper.getInstance()
.notifyClearMessages(
sessionId);
}
}).show();
break;
case ACTION_CLEAR_MESSAGE:
String title = context.getString(com.netease.nim.uikit.R.string.cloud_message_clear_tips);
CustomAlertDialog alertDialog = new CustomAlertDialog(context);
alertDialog.setTitle(title);
alertDialog.addItem("确定", () -> {
NIMClient.getService(MsgService.class).clearServerHistory(sessionId,
sessionType, true, "");
MessageListPanelHelper.getInstance().notifyClearMessages(sessionId);
});
String itemText = context.getString(com.netease.nim.uikit.R.string.sure_sync);
alertDialog.addItem(itemText, () -> {
NIMClient.getService(MsgService.class).clearServerHistory(sessionId,
sessionType, true, "");
MessageListPanelHelper.getInstance().notifyClearMessages(sessionId);
});
alertDialog.addItem("取消", () -> {
});
alertDialog.show();
break;
}
};
private static List<PopupMenuItem> getMoreMenuItems(Context context, String sessionId,
SessionTypeEnum sessionTypeEnum) {
List<PopupMenuItem> moreMenuItems = new ArrayList<PopupMenuItem>();
moreMenuItems.add(new PopupMenuItem(context, ACTION_HISTORY_QUERY_PERSIST_CLEAR, sessionId, sessionTypeEnum,
DemoCache.getContext().getString(com.netease.nim.uikit.R.string.message_history_query_ingore)));
moreMenuItems.add(new PopupMenuItem(context, ACTION_HISTORY_QUERY_NOT_PERSIST_CLEAR, sessionId, sessionTypeEnum,
DemoCache.getContext().getString(com.netease.nim.uikit.R.string.message_history_query_remember)));
moreMenuItems.add(new PopupMenuItem(context, ACTION_SEARCH_MESSAGE, sessionId, sessionTypeEnum,
DemoCache.getContext().getString(com.netease.nim.uikit.R.string.message_search_title)));
moreMenuItems.add(new PopupMenuItem(context, ACTION_CLEAR_MESSAGE_RECORD, sessionId, sessionTypeEnum,
DemoCache.getContext().getString(com.netease.nim.uikit.R.string.message_clear_record)));
moreMenuItems.add(new PopupMenuItem(context, ACTION_CLEAR_MESSAGE_NOT_RECORD, sessionId, sessionTypeEnum,
DemoCache.getContext().getString(com.netease.nim.uikit.R.string.message_clear_not_record)));
moreMenuItems.add(new PopupMenuItem(context, ACTION_CLEAR_MESSAGE, sessionId, sessionTypeEnum,
DemoCache.getContext().getString(com.netease.nim.uikit.R.string.cloud_message_clear)));
return moreMenuItems;
}
}
@@ -0,0 +1,43 @@
package cn.shangyu.gdxzExpert.netease.session.action;
import android.content.Intent;
import com.netease.nim.uikit.business.session.actions.BaseAction;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.activity.QuckMessageActivity;
import cn.shangyu.gdxzExpert.utils.UIUtils;
/**
* Created by hzxuwen on 2015/6/11.
*/
public class EasyAction extends BaseAction {
public EasyAction() {
super(R.drawable.ytx_chattingfooter_file_quick, R.string.app_panel_quickreply);
}
@Override
public void onClick() {
Intent intent = new Intent(UIUtils.getContext(),
QuckMessageActivity.class);
getActivity().startActivityForResult(intent,69);
// GuessAttachment attachment = new GuessAttachment();
// IMMessage message;
// if (getContainer() != null && getContainer().sessionType == SessionTypeEnum.ChatRoom) {
// message = ChatRoomMessageBuilder.createChatRoomCustomMessage(getAccount(), attachment);
// } else {
// message = MessageBuilder.createCustomMessage(getAccount(), getSessionType(), attachment.getValue().getDesc(), attachment);
// }
//
// sendMessage(message);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
}
@@ -0,0 +1,56 @@
package cn.shangyu.gdxzExpert.netease.session.action;
import static com.netease.nimlib.sdk.msg.constant.SessionTypeEnum.P2P;
import com.netease.nim.uikit.business.session.actions.BaseAction;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.ptop.MessageFragment;
import cn.shangyu.gdxzExpert.netease.session.extension.CustomAttachmentType;
import cn.shangyu.gdxzExpert.netease.session.extension.TeachAttachment;
import cn.shangyu.gdxzExpert.utils.SharePrefUtil;
public class HospitalAction extends BaseAction {
/**
* 构造函数
*
* @param iconResId 图标 res id
* @param titleId 图标标题的string res id
*/
public HospitalAction() {
super(R.drawable.ytx_chatting_hospital, R.string.app_panel_hospital);
}
@Override
public void onClick() {
// IWXAPI api = WXAPIFactory.createWXAPI(getActivity(), Constant.WeId);
// WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req();
// req.userName = "gh_9cd2fd72eb57"; // 填小程序原始id
// req.path = "/Pages/yishi/index/index"; //拉起小程序页面的可带参路径,不填默认拉起小程序首页,对于小游戏,可以只传入 query 部分,来实现传参效果,如:传入 "?foo=bar"。
// req.miniprogramType = WXLaunchMiniProgram.Req.MINIPROGRAM_TYPE_PREVIEW;// 可选打开 开发版,体验版和正式版
// api.sendReq(req);
String title = "肝胆相照互联网医院";
String netphoto=SharePrefUtil.getString(getActivity(),"netphoto","");
String multi_point_status=SharePrefUtil.getString(getActivity(),"multi_point_status","");
// String url = Url.getNewWa+"setInfo?patient_uuid="+ SharePrefUtil.getString(UIUtils.getContext(), "sessionUUID", getAccount()) +"&expert_uuid="+ SharePrefUtil.getString(UIUtils.getContext(), "uuid", "") ;
String content ="";
if("1".equals(multi_point_status))
{
content = getActivity().getResources().getStringArray(R.array.chat_menu_hospital)[1];
}
else
{
content = getActivity().getResources().getStringArray(R.array.chat_menu_hospital)[0];
}
String doctor_id=SharePrefUtil.getString(getActivity(),"doctor_id","");
// Log.d("gdxzzz",url+" ");
TeachAttachment teachAttachment=new TeachAttachment(title,"",content,doctor_id,
netphoto, CustomAttachmentType.Hostipal,"");
IMMessage message= MessageBuilder.createCustomMessage(getAccount(), P2P, CustomAttachmentType.Hostipal, teachAttachment);
message.setRemoteExtension(MessageFragment.ext);
sendMessage(message);
}
}
@@ -0,0 +1,183 @@
package cn.shangyu.gdxzExpert.netease.session.action;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.view.Gravity;
import androidx.annotation.NonNull;
import com.github.dfqin.grantor.PermissionListener;
import com.github.dfqin.grantor.PermissionsUtil;
import com.hjq.window.EasyWindow;
import com.netease.nim.uikit.business.session.actions.BaseAction;
import java.io.File;
import java.io.IOException;
import java.util.List;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.activity.PhotoAlbumActivity;
import cn.shangyu.gdxzExpert.ecdemo.common.utils.DemoUtils;
import cn.shangyu.gdxzExpert.ecdemo.common.utils.FileAccessor;
import cn.shangyu.gdxzExpert.ecdemo.common.utils.FileUtils;
import cn.shangyu.gdxzExpert.ecdemo.ui.chatting.model.ImgInfo;
import cn.shangyu.gdxzExpert.utils.LogUtil;
import top.zibin.luban.Luban;
/**
* Created by hzxuwen on 2015/6/12.
*/
public class ImageAction extends BaseAction {
public ImageAction() {
super(R.drawable.ytx_chattingfooter_image_selector, com.netease.nim.uikit.R.string.input_panel_photo);
}
@Override
public void onClick() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (PermissionsUtil.hasPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Intent intent=new Intent(getActivity(), PhotoAlbumActivity.class);
intent.putExtra("photonum", "-1");
getActivity().startActivityForResult(intent, 0x4);
} else {
EasyWindow.with(getActivity()).setGravity(Gravity.TOP).setYOffset(200).setWidth(1000)
.setContentView(R.layout.float_top_dialog_photo).show();
PermissionsUtil.requestPermission(getActivity(), new PermissionListener() {
@Override
public void permissionGranted(@NonNull String[] permissions) {
EasyWindow.cancelAll();
Intent intent=new Intent(getActivity(), PhotoAlbumActivity.class);
intent.putExtra("photonum", "-1");
getActivity().startActivityForResult(intent, 0x4);
}
@Override
public void permissionDenied(@NonNull String[] permissions) {
EasyWindow.cancelAll();
//用户拒绝了访问读写的申请
//
}
}, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE});
}
} else {
Intent intent=new Intent(getActivity(), PhotoAlbumActivity.class);
intent.putExtra("photonum", "-1");
getActivity().startActivityForResult(intent, 0x4);
}
}
/**
*
* @param filePath
* @return
*/
public static ImgInfo createImgInfo(String filePath, Context context) {
if(!FileUtils.checkFile(filePath) || FileAccessor.getImagePathName() == null) {
return null;
}
// int bitmapDegrees = DemoUtils.getBitmapDegrees(filePath);
String fileNameMD5 = DemoUtils.md5(System.currentTimeMillis() + filePath);
String bigFileFullName = fileNameMD5 + ".jpg";
LogUtil.i("bigFileFullName = "+bigFileFullName);
BitmapFactory.Options bitmapOptions = DemoUtils.getBitmapOptions(filePath);
String authorityDir = FileAccessor.getImagePathName().getAbsolutePath();
if((FileUtils.decodeFileLength(filePath) > 204800)
|| (bitmapOptions != null && (((bitmapOptions.outHeight > 1080) || (bitmapOptions.outWidth > 1080))))) {
File file = new File(authorityDir+File.separator+fileNameMD5);
if(!file.exists()) {
file.mkdirs();
}
try {
List<File> files= Luban.with(context).load(filePath).ignoreBy(1).setTargetDir(authorityDir).get();
String fileneme=files.get(0).getName();
FileAccessor.renameTo(authorityDir+File.separator, fileneme, bigFileFullName);
} catch (IOException e) {
e.printStackTrace();
}
// if(!DemoUtils.createThumbnailFromOrig(filePath, 1080, 1080, Bitmap.CompressFormat.JPEG, 100, FileAccessor.getImagePathName().getAbsolutePath(), fileNameMD5)) {
// return null;
// }
} else {
// file size small.
FileUtils.copyFile(authorityDir, fileNameMD5 , ".jpg", FileUtils.readFlieToByte(filePath, 0, FileUtils.decodeFileLength(filePath)));
}
// if((FileUtils.decodeFileLength(filePath) > 2097152))
// {
// if(bitmapDegrees != 0 && !DemoUtils.rotateCreateBitmapSmall(authorityDir +File.separator+ bigFileFullName, bitmapDegrees, Bitmap.CompressFormat.JPEG, authorityDir, bigFileFullName)) {
// return null;
// }
// }
// else{
// if(bitmapDegrees != 0 && !DemoUtils.rotateCreateBitmap(authorityDir +File.separator+ bigFileFullName, bitmapDegrees, Bitmap.CompressFormat.JPEG, authorityDir, bigFileFullName)) {
// return null;
// }
// }
LogUtil.d( "insert: compressed bigImgPath = " + bigFileFullName);
String thumbName = DemoUtils.md5(fileNameMD5 + System.currentTimeMillis());
// File file = new File(authorityDir);
// if(!file.exists()) {
// file.mkdirs();
// }
// if(!DemoUtils.createThumbnailFromOrig(authorityDir +File.separator+ bigFileFullName, 100, 100, Bitmap.CompressFormat.JPEG, 100, authorityDir, thumbName)) {
// return null;
// }
LogUtil.d( "insert: thumbName = " + thumbName);
ImgInfo imgInfo = new ImgInfo();
imgInfo.setBigImgPath(bigFileFullName);
imgInfo.setThumbImgPath(bigFileFullName);
imgInfo.isGif = false;
return imgInfo;
}
/**
*
* @param filePath
* @return
*/
public static ImgInfo createGIFImgInfo(String filePath) {
if(!FileUtils.checkFile(filePath) || FileAccessor.getImagePathName() == null) {
return null;
}
String fileNameMD5 = DemoUtils.md5(System.currentTimeMillis() + filePath);
String bigFileFullName = fileNameMD5 + ".gif";
String authorityDir = FileAccessor.getImagePathName().getAbsolutePath();
FileUtils.copyFile(authorityDir, fileNameMD5 , ".gif", FileUtils.readFlieToByte(filePath, 0, FileUtils.decodeFileLength(filePath)));
String thumbName = DemoUtils.md5(fileNameMD5 + System.currentTimeMillis());
File file = new File(authorityDir);
if(!file.exists()) {
file.mkdirs();
}
if(!DemoUtils.createThumbnailFromOrig(authorityDir + File.separator+ bigFileFullName, 100, 100, Bitmap.CompressFormat.JPEG, 100, authorityDir, thumbName)) {
return null;
}
ImgInfo imgInfo = new ImgInfo();
imgInfo.setBigImgPath(bigFileFullName);
imgInfo.setThumbImgPath(thumbName);
imgInfo.isGif = true;
return imgInfo;
}
}
@@ -0,0 +1,168 @@
package cn.shangyu.gdxzExpert.netease.session.action;
import static com.netease.nimlib.sdk.msg.constant.SessionTypeEnum.P2P;
import static cn.shangyu.gdxzExpert.netease.ptop.MessageFragment.cancelBackground;
import static cn.shangyu.gdxzExpert.netease.ptop.MessageFragment.lucencyBackground;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.ColorDrawable;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import com.netease.nim.uikit.business.session.actions.BaseAction;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import java.util.Arrays;
import java.util.List;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.ecdemo.view.IBaseAdapter;
import cn.shangyu.gdxzExpert.netease.ptop.MessageFragment;
import cn.shangyu.gdxzExpert.netease.session.extension.CustomAttachmentType;
import cn.shangyu.gdxzExpert.netease.session.extension.TeachAttachment;
import cn.shangyu.gdxzExpert.utils.SharePrefUtil;
import cn.shangyu.gdxzExpert.utils.UIUtils;
import cn.shangyu.gdxzExpert.utils.Url;
import cn.shangyu.gdxzExpert.widget.ECAlertDialog;
public class ShoppingAction extends BaseAction {
/**
* 构造函数
*
* @param iconResId 图标 res id
* @param titleId 图标标题的string res id
*/
public ShoppingAction() {
super(R.drawable.ytx_chattingfooter_shopping, R.string.app_panel_shopping);
}
@Override
public void onClick() {
showPopupWindow(getActivity().getWindow().getDecorView(),R.array.chat_menu_shop);
// ToastUtil.showToast("OnShoppingClick");
}
private void showPopupWindow(View view, int resourceIdArray) {
lucencyBackground(getActivity());
// 一个自定义的布局,作为显示的内容
View contentView = LayoutInflater.from(getActivity())
.inflate(R.layout.include_dialog_simplelist_big, null);
// 设置按钮的点击事件
ListView mListView = (ListView) contentView.findViewById(R.id.listview);
TextView dialog_tv_title=contentView.findViewById(R.id.dialog_tv_title);
dialog_tv_title.setVisibility(View.VISIBLE);
dialog_tv_title.setText("请选择");
View v0=contentView.findViewById(R.id.v0);
v0.setVisibility(View.VISIBLE);
contentView.findViewById(R.id.v1).setVisibility(View.VISIBLE);
String[] stringArray =getActivity().getResources().getStringArray(resourceIdArray);
final PopupWindow popupWindow = new PopupWindow(contentView,
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
popupWindow.setBackgroundDrawable(new ColorDrawable(0));
// 设置允许在外点击消失
popupWindow.setOutsideTouchable(true);
// 使其聚集获取焦点
popupWindow.setFocusable(true);
popupWindow
.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
mListView.setAdapter(new ListDialogAdapter(getActivity(), Arrays.asList(stringArray)));
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
if (position == 0) {
senddetail();
} else {
}
popupWindow.dismiss();
}
});
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
cancelBackground(getActivity());
}
});
popupWindow.showAtLocation(view, Gravity.CENTER, 0, 0);
}
private void senddetail()
{
ECAlertDialog dilaog2 = ECAlertDialog.buildAlert(getActivity(),
"您是否发送该商品详情?", "取消", "确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String title = getActivity().getResources().getStringArray(R.array.chat_menu_shop)[0];
String url = Url.getNewWa+"setInfo?patient_uuid="+SharePrefUtil.getString(UIUtils.getContext(), "sessionUUID", getAccount()) +"&expert_uuid="+ SharePrefUtil.getString(UIUtils.getContext(), "uuid", "") ;
String content = "肝胆相照®肝胆病在线公共服务平台";
Log.d("gdxzzz",url+" ");
IMMessage imMessage = MessageBuilder.createTextMessage(getAccount(), P2P, "纽娃复合营养素固体饮料主要成分是:蜂花粉、乳清蛋白粉、灰树花粉、低聚木糖、蚕蛹氨基酸、麦芽粉、薏苡仁粉、烟酸、磷脂,以及其他调味品、辅助原料。科学配比制成,含有丰富的蛋白质、氨基酸、维生素、微量元素及其他营养元素,点击链接了解详情。");
imMessage.setRemoteExtension(MessageFragment.ext);
sendMessage(imMessage);
TeachAttachment teachAttachment=new TeachAttachment(title,url,content,"",
"", CustomAttachmentType.Shopping,"");
IMMessage message= MessageBuilder.createCustomMessage(getAccount(), P2P, CustomAttachmentType.Shopping, teachAttachment);
message.setRemoteExtension(MessageFragment.ext);
sendMessage(message);
dialog.dismiss();
}
});
dilaog2.setCancelable(false);
dilaog2.getWindow();
dilaog2.show();
}
public class ListDialogAdapter extends IBaseAdapter<String> {
public ListDialogAdapter(Context ctx, List<String> data) {
super(ctx, data);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = this.mLayoutInflater.inflate(R.layout.listitem_dialog , null);
}
((TextView) convertView.findViewById(R.id.textview)).setText(getItem(position).toString());
convertView.findViewById(R.id.imageview).setVisibility(View.GONE);
// if(position==0)
// {
// ((TextView) convertView.findViewById(R.id.textview)).setTypeface(Typeface.DEFAULT_BOLD);
// }
// else
// {
//
// }
return convertView;
}
}
}
@@ -0,0 +1,135 @@
package cn.shangyu.gdxzExpert.netease.session.action;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import com.netease.nim.uikit.business.session.actions.BaseAction;
import java.util.Arrays;
import java.util.List;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.activity.PatientTeachActivity;
import cn.shangyu.gdxzExpert.activity.VideoTeachActivity;
import cn.shangyu.gdxzExpert.ecdemo.view.IBaseAdapter;
import static cn.shangyu.gdxzExpert.netease.ptop.MessageFragment.cancelBackground;
import static cn.shangyu.gdxzExpert.netease.ptop.MessageFragment.lucencyBackground;
/**
* Created by hzxuwen on 2015/6/11.
*/
public class TeachAction extends BaseAction {
public TeachAction() {
super(R.drawable.patient_teach_call, R.string.app_panel_video);
}
@Override
public void onClick() {
showPopupWindow(getActivity().getWindow().getDecorView(),R.array.chat_menu_teach);
// final ECListDialog dialog = new ECListDialog(getActivity(), new String[] { "图文科普",
// "视频科普" });
// dialog.setOnDialogItemClickListener(new ECListDialog.OnDialogItemClickListener() {
// @Override
// public void onDialogItemClick(Dialog d, int position) {
// if (position == 0) {
// Intent intent=new Intent(getActivity(), PatientTeachActivity.class);
// getActivity().startActivityForResult(intent, 70);
// dialog.dismiss();
// } else {
// Intent intent=new Intent(getActivity(), VideoTeachActivity.class);
// getActivity().startActivityForResult(intent, 70);
// dialog.dismiss();
//
// }
// }
// });
//
// dialog.setTitleColor(getActivity().getResources().getColor(R.color.top_title));
// dialog.show();
}
private void showPopupWindow(View view, int resourceIdArray) {
lucencyBackground(getActivity());
// 一个自定义的布局,作为显示的内容
View contentView = LayoutInflater.from(getActivity())
.inflate(R.layout.include_dialog_simplelist_big, null);
// 设置按钮的点击事件
ListView mListView = (ListView) contentView.findViewById(R.id.listview);
TextView dialog_tv_title=contentView.findViewById(R.id.dialog_tv_title);
dialog_tv_title.setVisibility(View.VISIBLE);
dialog_tv_title.setText("提示");
View v0=contentView.findViewById(R.id.v0);
v0.setVisibility(View.VISIBLE);
contentView.findViewById(R.id.v1).setVisibility(View.VISIBLE);
String[] stringArray =getActivity().getResources().getStringArray(resourceIdArray);
final PopupWindow popupWindow = new PopupWindow(contentView,
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
popupWindow.setBackgroundDrawable(new ColorDrawable(0));
// 设置允许在外点击消失
popupWindow.setOutsideTouchable(true);
// 使其聚集获取焦点
popupWindow.setFocusable(true);
popupWindow
.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
mListView.setAdapter(new ListDialogAdapter(getActivity(), Arrays.asList(stringArray)));
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
if (position == 0) {
Intent intent=new Intent(getActivity(), PatientTeachActivity.class);
getActivity().startActivityForResult(intent, 70);
} else {
Intent intent=new Intent(getActivity(), VideoTeachActivity.class);
getActivity().startActivityForResult(intent, 70);
}
popupWindow.dismiss();
}
});
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
cancelBackground(getActivity());
}
});
popupWindow.showAtLocation(view, Gravity.CENTER, 0, 0);
}
public class ListDialogAdapter extends IBaseAdapter<String> {
public ListDialogAdapter(Context ctx, List<String> data) {
super(ctx, data);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = this.mLayoutInflater.inflate(R.layout.listitem_dialog , null);
}
((TextView) convertView.findViewById(R.id.textview)).setText(getItem(position).toString());
convertView.findViewById(R.id.imageview).setVisibility(View.GONE);
return convertView;
}
}
}
@@ -0,0 +1,297 @@
package cn.shangyu.gdxzExpert.netease.session.action;
import static cn.shangyu.gdxzExpert.ecdemo.ui.chatting.ChattingFragment.getUriForFile;
import android.Manifest;
import android.app.Dialog;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.Gravity;
import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
import com.github.dfqin.grantor.PermissionListener;
import com.github.dfqin.grantor.PermissionsUtil;
import com.hjq.window.EasyWindow;
import com.netease.nim.uikit.business.session.actions.BaseAction;
import com.netease.nim.uikit.business.session.helper.VideoMessageHelper;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import java.io.File;
import java.io.IOException;
import java.io.InvalidClassException;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.ecdemo.common.ECPreferenceSettings;
import cn.shangyu.gdxzExpert.ecdemo.common.ECPreferences;
import cn.shangyu.gdxzExpert.ecdemo.common.utils.FileAccessor;
import cn.shangyu.gdxzExpert.ecdemo.ui.chatting.GlobalConstant;
import cn.shangyu.gdxzExpert.ecdemo.ui.chatting.VideoRecordActivity;
import cn.shangyu.gdxzExpert.widget.ECListDialog;
/**
* Created by hzxuwen on 2015/6/12.
*/
public class VideoAction extends BaseAction {
// 视频
protected transient VideoMessageHelper videoMessageHelper;
public VideoAction() {
super(R.drawable.ytx_chattingfooter_takephoto_selector, R.string.app_panel_tackpic);
}
@Override
public void onClick() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (PermissionsUtil.hasPermission(getActivity(), Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//有访问摄像头的权限
showDialog();
} else {
EasyWindow.with(getActivity()).setGravity(Gravity.TOP).setYOffset(200).setWidth(1000)
.setContentView(R.layout.float_top_dialog_new).show();
PermissionsUtil.requestPermission(getActivity(), new PermissionListener() {
@Override
public void permissionGranted(@NonNull String[] permissions) {
EasyWindow.cancelAll();
//用户授予了访问摄像头的权限
showDialog();
}
@Override
public void permissionDenied(@NonNull String[] permissions) {
EasyWindow.cancelAll();
//用户拒绝了访问摄像头的申请
}
}, new String[]{ Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE});
}
}
else
{
showDialog();
}
// videoHelper().showVideoSource(makeRequestCode(RequestCode.GET_LOCAL_VIDEO), makeRequestCode(RequestCode.CAPTURE_VIDEO));
}
private void showDialog()
{
ECListDialog dialog = new ECListDialog(getActivity(), R.array.take_chat_arr);
dialog.setOnDialogItemClickListener(new ECListDialog.OnDialogItemClickListener() {
@Override
public void onDialogItemClick(Dialog d, int position) {
if (position == 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (PermissionsUtil.hasPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// handleTackPicture();
takePhoto11();
} else {
EasyWindow.with(getActivity()).setGravity(Gravity.TOP).setYOffset(200).setWidth(1000)
.setContentView(R.layout.float_top_dialog_photo).show();
PermissionsUtil.requestPermission(getActivity(), new PermissionListener() {
@Override
public void permissionGranted(@NonNull String[] permissions) {
EasyWindow.cancelAll();
// handleTackPicture();
takePhoto11();
}
@Override
public void permissionDenied(@NonNull String[] permissions) {
EasyWindow.cancelAll();
//用户拒绝了访问读写的申请
//
}
}, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE});
}
} else {
handleTackPicture();
}
} else if (position == 1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (PermissionsUtil.hasPermission(getActivity(), Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//有访问录音
handleVideoRecord();
} else {
EasyWindow.with(getActivity()).setGravity(Gravity.TOP).setYOffset(200).setWidth(1000)
.setContentView(R.layout.float_top_dialog_record).show();
PermissionsUtil.requestPermission(getActivity(), new PermissionListener() {
@Override
public void permissionGranted(@NonNull String[] permissions) {
EasyWindow.cancelAll();
//用户授予了访问录音的权限
handleVideoRecord();
}
@Override
public void permissionDenied(@NonNull String[] permissions) {
EasyWindow.cancelAll();
//用户拒绝了访问录音的申请
// finish();
}
}, new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE});
}
}else {
handleVideoRecord();
}
}
}
});
dialog.setTitle(R.string.take_title);
dialog.show();
}
private void takePhoto11() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 设置打开相机
File photoFile = null;
try {
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); // 保存到公共共享空间内,可以在资源管理器中找到,其他应用也可以直接访问
// File storageDir = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES); 将图片放到应用专属空间内,其他的应用无法访问,也无法查看。随app的卸载而删除
String imageFileName = "fileName";
photoFile = File.createTempFile(imageFileName, ".jpg", storageDir);
// String filePath = photoFile.getAbsolutePath(); 获取到图片的路径,可以在onActivityResult中根据这个路径去获取图片
} catch (IOException e) {
e.printStackTrace();
}
if (photoFile != null) {
try {
ECPreferences.savePreference(
ECPreferenceSettings.SETTINGS_CROPIMAGE_OUTPUTPATH,
photoFile.getPath(), true);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(getActivity(),
getActivity().getPackageName() + ".fileprovider", photoFile));
getActivity().startActivityForResult(intent, 0x3);
} catch (InvalidClassException e) {
e.printStackTrace();
}
}
}
private void handleTackPicture() {
if (!FileAccessor.isExistExternalStore()) {
return;
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = FileAccessor.getTackPicFilePath();
if (file != null) {
/**
* 2018.11.24改
* */
Uri uri = getUriForFile(getActivity(),file);
if (uri != null) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
// mFilePath = file.getAbsolutePath();
try {
ECPreferences.savePreference(
ECPreferenceSettings.SETTINGS_CROPIMAGE_OUTPUTPATH,
file.getAbsolutePath(), true);
getActivity().startActivityForResult(intent, 0x3);
} catch (InvalidClassException e) {
e.printStackTrace();
}
}
}
// 调用系统打开视频
private void handleVideoRecord() {
Intent intent = new Intent();
intent.setClass(getActivity(), VideoRecordActivity.class);
getActivity().startActivityForResult(intent,
GlobalConstant.ACTIVITY_FOR_RESULT_VIDEORECORD);
}
/**
* ********************** 视频 *******************************
*/
private void initVideoMessageHelper() {
videoMessageHelper = new VideoMessageHelper(getActivity(), new VideoMessageHelper.VideoMessageHelperListener() {
@Override
public void onVideoPicked(File file, String md5) {
MediaPlayer mediaPlayer = getVideoMediaPlayer(file);
long duration = mediaPlayer == null ? 0 : mediaPlayer.getDuration();
int height = mediaPlayer == null ? 0 : mediaPlayer.getVideoHeight();
int width = mediaPlayer == null ? 0 : mediaPlayer.getVideoWidth();
IMMessage message = MessageBuilder.createVideoMessage(getAccount(), getSessionType(), file, duration, width, height, md5);
sendMessage(message);
}
});
}
/**
* 获取视频mediaPlayer
*
* @param file 视频文件
* @return mediaPlayer
*/
private MediaPlayer getVideoMediaPlayer(File file) {
try {
return MediaPlayer.create(getActivity(), Uri.fromFile(file));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// switch (requestCode) {
// if (requestCode == 0x3) {
// try {
// ECPreferences.savePreference(
// ECPreferenceSettings.SETTINGS_CROPIMAGE_OUTPUTPATH,
// file.getAbsolutePath(), true);
// Intent intent = new Intent(getActivity(), ImagePreviewActivity.class);
// getActivity().startActivityForResult(intent, 0x5);
// } catch (InvalidClassException e1) {
// e1.printStackTrace();
// }
// case RequestCode.GET_LOCAL_VIDEO:
// videoHelper().onGetLocalVideoResult(data);
// break;
// case RequestCode.CAPTURE_VIDEO:
// videoHelper().onCaptureVideoResult(data);
// break;
}
// }
private VideoMessageHelper videoHelper() {
if (videoMessageHelper == null) {
initVideoMessageHelper();
}
return videoMessageHelper;
}
}
@@ -0,0 +1,89 @@
package cn.shangyu.gdxzExpert.netease.session.action;
import static com.netease.nimlib.sdk.msg.constant.SessionTypeEnum.P2P;
import static cn.shangyu.gdxzExpert.netease.ptop.MessageFragment.havestopout;
import android.content.DialogInterface;
import android.content.Intent;
import com.netease.nim.uikit.business.session.actions.BaseAction;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.activity.OutofPatientNoticeActivity;
import cn.shangyu.gdxzExpert.netease.session.extension.CustomAttachmentType;
import cn.shangyu.gdxzExpert.netease.session.extension.TeachAttachment;
import cn.shangyu.gdxzExpert.utils.SharePrefUtil;
import cn.shangyu.gdxzExpert.utils.UIUtils;
import cn.shangyu.gdxzExpert.utils.Url;
import cn.shangyu.gdxzExpert.widget.ECAlertDialog;
/**
* Created by hzxuwen on 2015/6/11.
*/
public class VisitAction extends BaseAction {
public VisitAction() {
super(R.drawable.ytx_chattingfooter_chutingzhen, R.string.app_panel_outpatient);
}
@Override
public void onClick() {
ECAlertDialog dilaog2;
if (havestopout){
dilaog2 = ECAlertDialog.buildAlert(getActivity(),
"您是否发送您的出/停诊公告?", "取消", "确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String title = SharePrefUtil.getString(UIUtils.getContext(), "realName", "") + "医生门诊详情";
// String url = Url.urlOutpatient + SharePrefUtil.getString(UIUtils.getContext(), "uuid", "") + "&expert_name=" + SharePrefUtil.getString(UIUtils.getContext(), "realName", "");
String url = Url.urlOutpatientnew + SharePrefUtil.getString(UIUtils.getContext(), "uuid", "") ;
String content = "门诊详情";
// String content = "肝胆相照®肝胆病在线公共服务平台";
// String imagUrl = "http://tdoc.igandan.org/app/book/pdf/2019/20190613152617.png";
// Boolean videoKepu = true;
TeachAttachment teachAttachment=new TeachAttachment(title,url,content,"",
"", CustomAttachmentType.VisitTeach,"");
IMMessage message= MessageBuilder.createCustomMessage(getAccount(), P2P, CustomAttachmentType.VisitTeach, teachAttachment);
sendMessage(message);
dialog.dismiss();
}
});
dilaog2.setCancelable(false);
dilaog2.getWindow();
dilaog2.show();
}else {
dilaog2 = ECAlertDialog.buildAlert(getActivity(),
"您未添加出/停诊信息,是否添加?", "取消", "确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
getActivity().startActivity(new Intent(getActivity(), OutofPatientNoticeActivity.class));
dialog.dismiss();
}
});
dilaog2.setCancelable(false);
dilaog2.getWindow();
dilaog2.show();
}
}
}
@@ -0,0 +1,74 @@
package cn.shangyu.gdxzExpert.netease.session.extension;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachmentParser;
/**
* Created by zhoujianghua on 2015/4/9.
*/
public class CustomAttachParser implements MsgAttachmentParser {
private static final String KEY_TYPE = "type";
private static final String KEY_DATA = "";
@Override
public MsgAttachment parse(String json) {
CustomAttachment attachment = null;
try {
JSONObject object = JSON.parseObject(json);
// String type = object.getString(KEY_TYPE);
// JSONObject data = object.getJSONObject(KEY_DATA);
// String type = data.getString("messageType");
// switch (type) {
// case CustomAttachmentType.Teach:
// case CustomAttachmentType.VisitTeach:
// case CustomAttachmentType.VideoTeach:
// attachment = new TeachAttachment();
// break;
// case CustomAttachmentType.Guess:
// attachment = new GuessAttachment();
// break;
// case CustomAttachmentType.SnapChat:
// return new SnapChatAttachment(data);
// case CustomAttachmentType.Sticker:
// attachment = new StickerAttachment();
// break;
// case CustomAttachmentType.RTS:
// attachment = new RTSAttachment();
// break;
// case CustomAttachmentType.RedPacket:
// attachment = new RedPacketAttachment();
// break;
// case CustomAttachmentType.OpenedRedPacket:
// attachment = new RedPacketOpenedAttachment();
// break;
// case CustomAttachmentType.MultiRetweet:
// attachment = new MultiRetweetAttachment();
// break;
// default:
// attachment = new DefaultCustomAttachment();
// break;
// }
attachment = new TeachAttachment();
if (attachment != null) {
attachment.fromJson(object);
}
} catch (Exception e) {
}
return attachment;
}
public static String packData(String type, JSONObject data) {
// JSONObject object = new JSONObject();
// object.put(KEY_TYPE, type);
// if (data != null) {
// object.put(KEY_DATA, data);
// }
return data.toJSONString();
}
}
@@ -0,0 +1,35 @@
package cn.shangyu.gdxzExpert.netease.session.extension;
import com.alibaba.fastjson.JSONObject;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
/**
* Created by zhoujianghua on 2015/4/9.
*/
public abstract class CustomAttachment implements MsgAttachment {
protected String type;
public CustomAttachment(String type) {
this.type = type;
}
public void fromJson(JSONObject data) {
if (data != null) {
parseData(data);
}
}
@Override
public String toJson(boolean send) {
return CustomAttachParser.packData(type, packData());
}
public String getType() {
return type;
}
protected abstract void parseData(JSONObject data);
protected abstract JSONObject packData();
}
@@ -0,0 +1,21 @@
package cn.shangyu.gdxzExpert.netease.session.extension;
/**
* Created by zhoujianghua on 2015/4/9.
*/
public interface CustomAttachmentType {
// 多端统一
String Guess = "1";//石头剪刀布
String SnapChat = "2";//阅后即焚
String Sticker = "3";//贴图
String RTS = "4";//白板的发起结束消息
String RedPacket = "5";
String OpenedRedPacket = "6";
String MultiRetweet = "15";//多条消息合并转发
String Teach="[图文科普]";
String VideoTeach="[视频科普]";
String VisitTeach="[门诊公告]";
String CouTeach="[公益咨询]";
String Shopping="[肝胆商城]";
String Hostipal="[互联网医院]";
}
@@ -0,0 +1,35 @@
package cn.shangyu.gdxzExpert.netease.session.extension;
import com.alibaba.fastjson.JSONObject;
/**
* Created by zhoujianghua on 2015/4/10.
*/
public class DefaultCustomAttachment extends CustomAttachment {
private String content;
public DefaultCustomAttachment() {
super("0");
}
@Override
protected void parseData(JSONObject data) {
content = data.toJSONString();
}
@Override
protected JSONObject packData() {
JSONObject data = null;
try {
data = JSONObject.parseObject(content);
} catch (Exception e) {
}
return data;
}
public String getContent() {
return content;
}
}
@@ -0,0 +1,70 @@
package cn.shangyu.gdxzExpert.netease.session.extension;
import com.alibaba.fastjson.JSONObject;
import java.util.Random;
/**
* Created by zhoujianghua on 2015/4/9.
*/
public class GuessAttachment extends CustomAttachment {
public enum Guess {
Shitou(1, "石头"),
Jiandao(2, "剪刀"),
Bu(3, "布"),;
private int value;
private String desc;
Guess(int value, String desc) {
this.value = value;
this.desc = desc;
}
static Guess enumOfValue(int value) {
for (Guess direction : values()) {
if (direction.getValue() == value) {
return direction;
}
}
return Shitou;
}
public int getValue() {
return value;
}
public String getDesc() {
return desc;
}
}
private Guess value;
public GuessAttachment() {
super(CustomAttachmentType.Guess);
random();
}
@Override
protected void parseData(JSONObject data) {
value = Guess.enumOfValue(data.getIntValue("value"));
}
@Override
protected JSONObject packData() {
JSONObject data = new JSONObject();
data.put("value", value.getValue());
return data;
}
private void random() {
int value = new Random().nextInt(3) + 1;
this.value = Guess.enumOfValue(value);
}
public Guess getValue() {
return value;
}
}
@@ -0,0 +1,263 @@
package cn.shangyu.gdxzExpert.netease.session.extension;
import android.text.TextUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
/*
{
"sessionID":"session_id",
"sessionName":"session_name",
"url": "https://netease.im",//nos
"md5": "d5ff5301b95fb9a23566ed407ebbc177",//nos file
"compressed": false,
"encrypted": true,
"password": "b95fb9a23566ed40",//rc4
"messageAbstract":
[//消息摘要,前两条消息摘要Json
{
"sender": "allday1",
"message": "123313123123123123"//文本消息,最大32字,超过32使用32字 + "......"
},
{
"sender": "allday1",
"message": "[视频]"
}
]
}
*/
public class MultiRetweetAttachment extends CustomAttachment {
private static final String KEY_SESSION_ID = "sessionID";
private static final String KEY_SESSION_NAME = "sessionName";
private static final String KEY_URL = "url";
private static final String KEY_MD5 = "md5";
private static final String KEY_COMPRESSED = "compressed";
private static final String KEY_ENCRYPTED = "encrypted";
private static final String KEY_PASSWORD = "password";
private static final String KEY_MESSAGE_ABSTRACT = "messageAbstract";
private static final String KEY_SENDER = "sender";
private static final String KEY_MESSAGE = "message";
private String sessionID;
private String sessionName;
/** nos文件存储地址 */
private String url;
private String md5;
private boolean compressed;
private boolean encrypted;
private String password;
/** 第一条消息的发送者ID */
private String sender1;
/** 第一条消息在合并转发消息中的展示文案 */
private String message1;
/** 第二条消息的发送者ID */
private String sender2;
/** 第二条消息在合并转发消息中的展示文案 */
private String message2;
public MultiRetweetAttachment() {
super(CustomAttachmentType.MultiRetweet);
}
public MultiRetweetAttachment(String sessionID, String sessionName, String url, String md5, boolean compressed, boolean encrypted, String password, String sender1, String message1, String sender2, String message2) {
super(CustomAttachmentType.MultiRetweet);
this.sessionID = sessionID;
this.sessionName = sessionName;
this.url = url;
this.md5 = md5;
this.compressed = compressed;
this.encrypted = encrypted;
this.password = password;
this.sender1 = sender1;
this.message1 = message1;
this.sender2 = sender2;
this.message2 = message2;
}
@Override
protected void parseData(JSONObject data) {
//如果Json格式包含外层部分,则先进入内层
if (data.containsKey("data")) {
data = data.getJSONObject("data");
}
try {
sessionID = data.getString(KEY_SESSION_ID);
sessionName = data.getString(KEY_SESSION_NAME);
url = data.getString(KEY_URL);
md5 = data.getString(KEY_MD5);
compressed = data.getBooleanValue(KEY_COMPRESSED);
encrypted = data.getBooleanValue(KEY_ENCRYPTED);
password = data.getString(KEY_PASSWORD);
JSONArray msgAbs = data.getJSONArray(KEY_MESSAGE_ABSTRACT);
JSONObject obj1 = msgAbs.getJSONObject(0);
sender1 = obj1.getString(KEY_SENDER);
message1 = obj1.getString(KEY_MESSAGE);
if (msgAbs.size()>1){
JSONObject obj2 = msgAbs.getJSONObject(1);
sender2 = obj2.getString(KEY_SENDER);
message2 = obj2.getString(KEY_MESSAGE);
}
} catch (Exception e) {
//转化失败,条目显示null字符
e.printStackTrace();
}
}
@Override
protected JSONObject packData() {
JSONObject data = new JSONObject();
data.put(KEY_SESSION_ID, sessionID);
data.put(KEY_SESSION_NAME, sessionName);
data.put(KEY_URL, url);
data.put(KEY_MD5, md5);
data.put(KEY_COMPRESSED, compressed);
data.put(KEY_ENCRYPTED, encrypted);
data.put(KEY_PASSWORD, password);
JSONArray messageAbstract = new JSONArray();
JSONObject obj1 = new JSONObject();
obj1.put(KEY_SENDER, sender1);
obj1.put(KEY_MESSAGE, message1);
messageAbstract.add(obj1);
//只有一条消息时,不传递第二组的字段
if (!TextUtils.isEmpty(sender2)) {
JSONObject obj2 = new JSONObject();
obj2.put(KEY_SENDER, sender2);
obj2.put(KEY_MESSAGE, message2);
messageAbstract.add(obj2);
}
data.put(KEY_MESSAGE_ABSTRACT, messageAbstract);
return data;
}
public static String getKeySessionId() {
return KEY_SESSION_ID;
}
public static String getKeySessionName() {
return KEY_SESSION_NAME;
}
public static String getKeyUrl() {
return KEY_URL;
}
public static String getKeyMd5() {
return KEY_MD5;
}
public static String getKeyCompressed() {
return KEY_COMPRESSED;
}
public static String getKeyEncrypted() {
return KEY_ENCRYPTED;
}
public static String getKeyPassword() {
return KEY_PASSWORD;
}
public static String getKeyMessageAbstract() {
return KEY_MESSAGE_ABSTRACT;
}
public static String getKeySender() {
return KEY_SENDER;
}
public static String getKeyMessage() {
return KEY_MESSAGE;
}
public String getSessionID() {
return sessionID;
}
public void setSessionID(String sessionID) {
this.sessionID = sessionID;
}
public String getSessionName() {
return sessionName;
}
public void setSessionName(String sessionName) {
this.sessionName = sessionName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMd5() {
return md5;
}
public void setMd5(String md5) {
this.md5 = md5;
}
public boolean isCompressed() {
return compressed;
}
public void setCompressed(boolean compressed) {
this.compressed = compressed;
}
public boolean isEncrypted() {
return encrypted;
}
public void setEncrypted(boolean encrypted) {
this.encrypted = encrypted;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSender1() {
return sender1;
}
public void setSender1(String sender1) {
this.sender1 = sender1;
}
public String getMessage1() {
return message1;
}
public void setMessage1(String message1) {
this.message1 = message1;
}
public String getSender2() {
return sender2;
}
public void setSender2(String sender2) {
this.sender2 = sender2;
}
public String getMessage2() {
return message2;
}
public void setMessage2(String message2) {
this.message2 = message2;
}
}
@@ -0,0 +1,59 @@
package cn.shangyu.gdxzExpert.netease.session.extension;
import com.alibaba.fastjson.JSONObject;
public class RedPacketAttachment extends CustomAttachment {
private String content;// 消息文本内容
private String redPacketId;// 红包id
private String title;// 红包名称
private static final String KEY_CONTENT = "content";
private static final String KEY_ID = "redPacketId";
private static final String KEY_TITLE = "title";
public RedPacketAttachment() {
super(CustomAttachmentType.RedPacket);
}
@Override
protected void parseData(JSONObject data) {
content = data.getString(KEY_CONTENT);
redPacketId = data.getString(KEY_ID);
title = data.getString(KEY_TITLE);
}
@Override
protected JSONObject packData() {
JSONObject data = new JSONObject();
data.put(KEY_CONTENT, content);
data.put(KEY_ID, redPacketId);
data.put(KEY_TITLE, title);
return data;
}
public String getRpContent() {
return content;
}
public String getRpId() {
return redPacketId;
}
public String getRpTitle() {
return title;
}
public void setRpContent(String content) {
this.content = content;
}
public void setRpId(String briberyID) {
this.redPacketId = briberyID;
}
public void setRpTitle(String briberyName) {
this.title = briberyName;
}
}
@@ -0,0 +1,120 @@
package cn.shangyu.gdxzExpert.netease.session.extension;
import com.alibaba.fastjson.JSONObject;
import com.netease.nim.uikit.business.team.helper.TeamHelper;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import cn.shangyu.gdxzExpert.netease.DemoCache;
import cn.shangyu.gdxzExpert.netease.uinfo.UserInfoHelper;
public class RedPacketOpenedAttachment extends CustomAttachment {
private String sendAccount; //发送红包ID
private String openAccount; //打开红包ID
private String redPacketId; //红包ID
private boolean isGetDone; //是否被领完
private static final String KEY_SEND = "sendPacketId";
private static final String KEY_OPEN = "openPacketId";
private static final String KEY_RP_ID = "redPacketId";
private static final String KEY_DONE = "isGetDone";
public RedPacketOpenedAttachment() {
super(CustomAttachmentType.OpenedRedPacket);
}
public String getSendNickName(SessionTypeEnum sessionTypeEnum, String targetId) {
if (DemoCache.getAccount().equals(sendAccount) && DemoCache.getAccount().equals(openAccount)) {
return "自己";
}
return getDisplayName(sessionTypeEnum, targetId, sendAccount);
}
public String getOpenNickName(SessionTypeEnum sessionTypeEnum, String targetId) {
return getDisplayName(sessionTypeEnum, targetId, openAccount);
}
// 我发的红包或者是我打开的红包
public boolean belongTo(String account) {
if (openAccount == null || sendAccount == null || account == null) {
return false;
}
return openAccount.equals(account) || sendAccount.equals(account);
}
private String getDisplayName(SessionTypeEnum sessionTypeEnum, String targetId, String account) {
if (sessionTypeEnum == SessionTypeEnum.Team) {
return TeamHelper.getTeamMemberDisplayNameYou(targetId, account);
} else if (sessionTypeEnum == SessionTypeEnum.P2P) {
return UserInfoHelper.getUserDisplayNameEx(account, "你");
} else {
return "";
}
}
public String getDesc(SessionTypeEnum sessionTypeEnum, String targetId) {
String sender = getSendNickName(sessionTypeEnum, targetId);
String opened = getOpenNickName(sessionTypeEnum, targetId);
return String.format("%s领取了%s的红包", opened, sender);
}
public String getSendAccount() {
return sendAccount;
}
private void setSendAccount(String sendAccount) {
this.sendAccount = sendAccount;
}
public String getOpenAccount() {
return openAccount;
}
private void setOpenAccount(String openAccount) {
this.openAccount = openAccount;
}
public String getRedPacketId() {
return redPacketId;
}
private void setRedPacketId(String redPacketId) {
this.redPacketId = redPacketId;
}
public boolean isRpGetDone() {
return isGetDone;
}
private void setIsGetDone(boolean isGetDone) {
this.isGetDone = isGetDone;
}
@Override
protected void parseData(JSONObject data) {
sendAccount = data.getString(KEY_SEND);
openAccount = data.getString(KEY_OPEN);
redPacketId = data.getString(KEY_RP_ID);
isGetDone = data.getBoolean(KEY_DONE);
}
@Override
protected JSONObject packData() {
JSONObject jsonObj = new JSONObject();
jsonObj.put(KEY_SEND, sendAccount);
jsonObj.put(KEY_OPEN, openAccount);
jsonObj.put(KEY_RP_ID, redPacketId);
jsonObj.put(KEY_DONE, isGetDone);
return jsonObj;
}
public static RedPacketOpenedAttachment obtain(String sendPacketId, String openPacketId, String packetId, boolean isGetDone) {
RedPacketOpenedAttachment model = new RedPacketOpenedAttachment();
model.setRedPacketId(packetId);
model.setSendAccount(sendPacketId);
model.setOpenAccount(openPacketId);
model.setIsGetDone(isGetDone);
return model;
}
}
@@ -0,0 +1,120 @@
package cn.shangyu.gdxzExpert.netease.session.extension;
import com.alibaba.fastjson.JSONObject;
/**
* Created by zhoujianghua on 2015/4/9.
*/
public class TeachAttachment extends CustomAttachment {
String title;//标题
String url;//内容url
String content;//内容
String messigeid;//id
String messagephoto;//照片
String type;//类型
String gdxz_ext_data;//备用字段,json字符串
public TeachAttachment(String title,String url,String content,String messigeid,String messagephoto,String type,String gdxz_ext_data)
{
super(CustomAttachmentType.Teach);
this.title=title;
this.url=url;
this.content=content;
this.messigeid=messigeid;
this.messagephoto=messagephoto;
this.type=type;
this.gdxz_ext_data=gdxz_ext_data;
}
public TeachAttachment() {
super(CustomAttachmentType.Teach);
}
@Override
protected void parseData(JSONObject data) {
// value = Guess.enumOfValue(data.getIntValue("value"));
this.title=data.getString("gdxz_title");
this.url=data.getString("gdxz_url");
this.content=data.getString("gdxz_content");
this.messigeid=data.getString("gdxz_id");
this.messagephoto=data.getString("gdxz_img");
this.type=data.getString("gdxz_type");
this.gdxz_ext_data=data.getString("gdxz_ext_data");
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getMessigeid() {
return messigeid;
}
public void setMessigeid(String messigeid) {
this.messigeid = messigeid;
}
public String getMessagephoto() {
return messagephoto;
}
public void setMessagephoto(String messagephoto) {
this.messagephoto = messagephoto;
}
public String getGdxz_ext_data() {
return gdxz_ext_data;
}
public void setGdxz_ext_data(String gdxz_ext_data) {
this.gdxz_ext_data = gdxz_ext_data;
}
@Override
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
protected JSONObject packData() {
JSONObject data = new JSONObject();
data.put("gdxz_title", getTitle());
data.put("gdxz_url",getUrl());
data.put("gdxz_content",getContent());
data.put("gdxz_id",getMessigeid());
data.put("gdxz_img",getMessagephoto());
data.put("gdxz_type",getType());
data.put("gdxz_ext_data",getType());//备用字段,json字符串
return data;
}
}
@@ -0,0 +1,123 @@
package cn.shangyu.gdxzExpert.netease.session.viewholder;
import android.content.Intent;
import com.netease.nim.uikit.R;
import com.netease.nim.uikit.business.session.viewholder.MsgViewHolderThumbBase;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseMultiItemFetchLoadAdapter;
import com.netease.nim.uikit.common.util.media.ImageUtil;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.msg.MessageBuilder;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.attachment.ImageAttachment;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import cn.shangyu.gdxzExpert.ecdemo.ui.chatting.ImageGralleryPagerActivity;
import cn.shangyu.gdxzExpert.ecdemo.ui.chatting.ViewImageInfo;
import cn.shangyu.gdxzExpert.utils.UIUtils;
/**
* Created by zhoujianghua on 2015/8/4.
*/
public class MsgViewHolderPicture extends MsgViewHolderThumbBase {
public MsgViewHolderPicture(BaseMultiItemFetchLoadAdapter adapter) {
super(adapter);
}
@Override
public int getContentResId() {
return R.layout.nim_message_item_picture;
}
@Override
public void onItemClick() {
// WatchMessagePictureActivity.start(context, message);
queryImageMessages();
}
@Override
protected String thumbFromSourceFile(String path) {
return path;
}
List<IMMessage> imageMsgList = new ArrayList<>();
// List<ImgInfo> imgInfos=new ArrayList<>();
ArrayList<ViewImageInfo> urls =new ArrayList<>();
// 查询并显示图片,带viewPager
private void queryImageMessages() {
imageMsgList.clear();
IMMessage anchor = MessageBuilder.createEmptyMessage(message.getSessionId(), message.getSessionType(), 0);
NIMClient.getService(MsgService.class).queryMessageListByType(MsgTypeEnum.image, anchor, Integer.MAX_VALUE).setCallback(new RequestCallback<List<IMMessage>>() {
@Override
public void onSuccess(List<IMMessage> param) {
for (IMMessage imMessage : param) {
MsgAttachment attachment = imMessage.getAttachment();
if (attachment instanceof ImageAttachment && !ImageUtil.isGif(((ImageAttachment) attachment).getExtension())){
imageMsgList.add(imMessage);
}
}
// imageMsgList.addAll(param);
Collections.reverse(imageMsgList);
setDisplayIndex();
}
@Override
public void onFailed(int code) {
}
@Override
public void onException(Throwable exception) {
}
});
}
// 设置第一个选中的图片index
private void setDisplayIndex() {
urls.clear();
for(IMMessage imageObject:imageMsgList)
{
new ViewImageInfo("","");
urls.add(new ViewImageInfo(((ImageAttachment)(imageObject.getAttachment())).getUrl(),
((ImageAttachment)(imageObject.getAttachment())).getUrl()));
}
for (int i = 0; i < imageMsgList.size(); i++) {
IMMessage imageObject = imageMsgList.get(i);
// ImgInfo createImgInfo = ImgInfoSqlManager.getInstance().createImgInfo(
// ((ImageAttachment)(imageObject.getAttachment())).getPath(), UIUtils.getContext());
// imgInfos.add(createImgInfo);
// new ViewImageInfo("","");
// urls.add(new ViewImageInfo(((ImageAttachment)(imageObject.getAttachment())).getUrl(),
// ((ImageAttachment)(imageObject.getAttachment())).getUrl()));
if (compareObjects(message, imageObject)) {
// firstDisplayImageIndex = i;
Intent intent = new Intent(UIUtils.getContext(), ImageGralleryPagerActivity.class);
intent.putExtra(ImageGralleryPagerActivity.EXTRA_IMAGE_INDEX, i);
intent.putParcelableArrayListExtra(ImageGralleryPagerActivity.EXTRA_IMAGE_URLS, urls);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
UIUtils.getContext().startActivity(intent);
break;
}
}
}
protected boolean compareObjects(IMMessage t1, IMMessage t2) {
return (t1.getUuid().equals(t2.getUuid()));
}
@Override
protected boolean isShowBubble() {
return false;
}
}
@@ -0,0 +1,229 @@
package cn.shangyu.gdxzExpert.netease.session.viewholder;
import static android.widget.ImageView.ScaleType.CENTER;
import static com.mobile.auth.gatewayauth.utils.ReflectionUtils.getActivity;
import static cn.shangyu.gdxzExpert.utils.Url.getNewWa;
import android.content.Intent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.netease.nim.uikit.business.session.viewholder.MsgViewHolderBase;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseMultiItemFetchLoadAdapter;
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.activity.NewsDetailActivity;
import cn.shangyu.gdxzExpert.activity.PublicServiceDetailsActivity;
import cn.shangyu.gdxzExpert.activity.VideoDetilActivity;
import cn.shangyu.gdxzExpert.netease.session.extension.CustomAttachmentType;
import cn.shangyu.gdxzExpert.netease.session.extension.TeachAttachment;
import cn.shangyu.gdxzExpert.utils.CommonUtil;
import cn.shangyu.gdxzExpert.utils.Constant;
import cn.shangyu.gdxzExpert.utils.StringUtil;
import cn.shangyu.gdxzExpert.utils.UIUtils;
/**
* Created by huangjun on 2015/11/25.
* Tip类型消息ViewHolder
*/
public class MsgViewHolderTeach extends MsgViewHolderBase {
protected TextView tv_location;
protected TextView tv_pre_content;
private RelativeLayout re_location;
private ImageView iv_rich;
private TeachAttachment teachAttachment;
public MsgViewHolderTeach(BaseMultiItemFetchLoadAdapter adapter) {
super(adapter);
}
@Override
public int getContentResId() {
if(CommonUtil.BigModule())
{
return R.layout.chatting_item_rich_text_tobig;
}
else
{
return R.layout.chatting_item_rich_text_to;
}
}
@Override
public void inflateContentView() {
// notificationTextView = (TextView) view.findViewById(com.netease.nim.uikit.R.id.message_item_notification_label);
tv_location=view.findViewById(R.id.tv_location);
tv_pre_content=view.findViewById(R.id.tv_pre_content);
re_location=view.findViewById(R.id.re_location);
iv_rich=view.findViewById(R.id.iv_rich);
}
@Override
public void bindContentView() {
if (message.getAttachment() == null) {
return;
}
teachAttachment= (TeachAttachment)message.getAttachment();
if(teachAttachment.getType()!=null)
{
if(teachAttachment.getType().equals(CustomAttachmentType.CouTeach))
{
// tv_location.setVisibility(View.GONE);
tv_location.setText(teachAttachment.getTitle()+"");
tv_pre_content.setText("点击查看问题详情");
iv_rich.setScaleType(CENTER);
iv_rich.setImageResource(R.drawable.icon_chatting_file);
// iv_rich.setBackgroundDrawable(UIUtils.getContext().getResources().getDrawable(R.drawable.icon_chatting_file));
// re_location.setBackgroundResource(R.drawable.chat_to_bg_fiel);
}
else if(teachAttachment.getType().equals(CustomAttachmentType.VisitTeach))
{
// tv_location.setVisibility(View.VISIBLE);
tv_location.setText(teachAttachment.getTitle()+"");
tv_pre_content.setText("肝胆相照®肝胆病在线公共服务平台");
iv_rich.setImageResource(R.drawable.mind_logo);
// re_location.setBackgroundResource(R.drawable.chatto_bg);
}
else
{
// tv_location.setVisibility(View.VISIBLE);
tv_location.setText(teachAttachment.getTitle()+"");
if(StringUtil.isEmpty(teachAttachment.getContent()))
{
tv_pre_content.setText("肝胆相照®肝胆病在线公共服务平台");
}
else
{
tv_pre_content.setText(teachAttachment.getContent());
}
if(teachAttachment.getTitle()!=null&&teachAttachment.getTitle().contains("互联网医院"))
{
Glide.with(getActivity()).load(
teachAttachment.getMessagephoto()).apply(
new RequestOptions().fitCenter()).into(iv_rich);
}
else
{
iv_rich.setImageResource(R.drawable.mind_logo);
}
// re_location.setBackgroundResource(R.drawable.chatto_bg);
}
}
re_location.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(teachAttachment.getType().equals(CustomAttachmentType.CouTeach))
{
;
Intent intent = new Intent(UIUtils.getContext(), PublicServiceDetailsActivity.class);
intent.putExtra("consultUuid", teachAttachment.getMessigeid());
intent.putExtra("isCloseAnswer", true);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
UIUtils.getContext().startActivity(intent);
}
else if(teachAttachment.getTitle()!=null&&teachAttachment.getTitle().contains("互联网医院"))
{
IWXAPI api = WXAPIFactory.createWXAPI(getActivity(), Constant.WeId);
WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req();
req.userName = "gh_9cd2fd72eb57"; // 填小程序原始id
req.path = "/Pages/yishi/index/index"; //拉起小程序页面的可带参路径,不填默认拉起小程序首页,对于小游戏,可以只传入 query 部分,来实现传参效果,如:传入 "?foo=bar"。
// req.miniprogramType = WXLaunchMiniProgram.Req.MINIPROGRAM_TYPE_PREVIEW;// 可选打开 开发版,体验版和正式版
api.sendReq(req);
}
else
{
Intent intent;
if (!StringUtil.isEmpty(teachAttachment.getUrl())&&teachAttachment.getUrl().contains("video")){
intent = new Intent(UIUtils.getContext(), VideoDetilActivity.class);
intent.putExtra("uuid", teachAttachment.getMessigeid());
}else {
intent = new Intent(UIUtils.getContext(), NewsDetailActivity.class);
}
if (!StringUtil.isEmpty(teachAttachment.getUrl())&&teachAttachment.getUrl().contains("outpatient_details")
||!StringUtil.isEmpty(teachAttachment.getUrl())&&teachAttachment.getUrl().contains("wxPatient/index.htm#/outPatient")){
intent.putExtra("title", "门诊详情");
}else if(!StringUtil.isEmpty(teachAttachment.getUrl())&&teachAttachment.getUrl().contains(getNewWa))
{
intent.putExtra("title", UIUtils.getContext().getResources().getStringArray(R.array.chat_menu_shop)[0]);
intent.putExtra("flag", 1);
}
else
{
intent.putExtra("newsTitle", teachAttachment.getTitle()+"");
intent.putExtra("kepuuuid", teachAttachment.getMessigeid());
intent.putExtra("title", "患教详情");
intent.putExtra("need_inside_share", "no");
}
if(!StringUtil.isEmpty(teachAttachment.getUrl())
&&teachAttachment.getUrl().contains("dcsvip1imapp.cloopen.net:8888"))
{
intent.putExtra("url",
((TeachAttachment) message.getAttachment()).getUrl().split("http://dcsvip1imapp.cloopen.net:8888")[1]);
}
else
{
intent.putExtra("url", teachAttachment.getUrl());
}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
UIUtils.getContext().startActivity(intent);
}
}
});
re_location.setOnLongClickListener(longClickListener);
// if (TextUtils.isEmpty(message.getContent())) {
// Map<String, Object> content = message.getRemoteExtension();
// if (content != null && !content.isEmpty()) {
// text = (String) content.get("content");
// }
// } else {
// text = message.getContent();
// }
// handleTextNotification(text);
}
private void handleTextNotification(String text) {
// MoonUtil.identifyFaceExpressionAndATags(context, notificationTextView, text, ImageSpan.ALIGN_BOTTOM);
// notificationTextView.setMovementMethod(LinkMovementMethod.getInstance());
}
// @Override
// public void onItemClick()
// {
//
// }
@Override
protected boolean isMiddleItem() {
return false;
}
@Override
protected boolean isShowBubble() {
return false;
}
}
@@ -0,0 +1,60 @@
package cn.shangyu.gdxzExpert.netease.session.viewholder;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ImageSpan;
import android.widget.TextView;
import com.netease.nim.uikit.business.session.emoji.MoonUtil;
import com.netease.nim.uikit.business.session.viewholder.MsgViewHolderBase;
import com.netease.nim.uikit.common.ui.recyclerview.adapter.BaseMultiItemFetchLoadAdapter;
import java.util.Map;
/**
* Created by huangjun on 2015/11/25.
* Tip类型消息ViewHolder
*/
public class MsgViewHolderTip extends MsgViewHolderBase {
protected TextView notificationTextView;
public MsgViewHolderTip(BaseMultiItemFetchLoadAdapter adapter) {
super(adapter);
}
@Override
public int getContentResId() {
return com.netease.nim.uikit.R.layout.nim_message_item_notification;
}
@Override
public void inflateContentView() {
notificationTextView = (TextView) view.findViewById(com.netease.nim.uikit.R.id.message_item_notification_label);
}
@Override
public void bindContentView() {
String text = "未知通知提醒";
if (TextUtils.isEmpty(message.getContent())) {
Map<String, Object> content = message.getRemoteExtension();
if (content != null && !content.isEmpty()) {
text = (String) content.get("content");
}
} else {
text = message.getContent();
}
handleTextNotification(text);
}
private void handleTextNotification(String text) {
MoonUtil.identifyFaceExpressionAndATags(context, notificationTextView, text, ImageSpan.ALIGN_BOTTOM);
notificationTextView.setMovementMethod(LinkMovementMethod.getInstance());
}
@Override
protected boolean isMiddleItem() {
return true;
}
}
@@ -0,0 +1,231 @@
package cn.shangyu.gdxzExpert.netease.thridparty;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.netease.nim.uikit.business.session.helper.MessageHelper;
import com.netease.nim.uikit.common.http.HttpClientWrapper;
import com.netease.nim.uikit.common.http.NimHttpClient;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.chatroom.model.ChatRoomInfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import cn.shangyu.gdxzExpert.netease.DemoCache;
import cn.shangyu.gdxzExpert.netease.DemoPrivatizationConfig;
import cn.shangyu.gdxzExpert.netease.config.DemoServers;
/**
* 网易云信Demo聊天室Http客户端。第三方开发者请连接自己的应用服务器。
* <p/>
* Created by huangjun on 2016/1/18.
*/
public class ChatRoomHttpClient {
private static final String TAG = ChatRoomHttpClient.class.getSimpleName();
// code
private static final int RESULT_CODE_SUCCESS = 200;
// api
private static final String API_NAME_CHAT_ROOM_LIST = "homeList";
private static final String API_NAME_CHAT_ROOM_ADDRESS = "requestAddress";
// header
private static final String HEADER_KEY_APP_KEY = "appkey";
// request
private static final String REQUEST_KEY_UID = "uid";
private static final String REQUEST_KEY_ROOM_ID = "roomid";
private static final String REQUEST_KEY_TYPE = "type";
// result
private static final String RESULT_KEY_RES = "res";
private static final String RESULT_KEY_ERROR_MSG = "errmsg";
private static final String RESULT_KEY_MSG = "msg";
private static final String RESULT_KEY_TOTAL = "total";
private static final String RESULT_KEY_LIST = "list";
private static final String RESULT_KEY_NAME = "name";
private static final String RESULT_KEY_CREATOR = "creator";
private static final String RESULT_KEY_STATUS = "status";
private static final String RESULT_KEY_ANNOUNCEMENT = "announcement";
private static final String RESULT_KEY_EXT = "ext";
private static final String RESULT_KEY_ROOM_ID = "roomid";
private static final String RESULT_KEY_BROADCAST_URL = "broadcasturl";
private static final String RESULT_KEY_ONLINE_USER_COUNT = "onlineusercount";
private static final String RESULT_KEY_ADDR = "addr";
public interface ChatRoomHttpCallback<T> {
void onSuccess(T t);
void onFailed(int code, String errorMsg);
}
private static ChatRoomHttpClient instance;
public static synchronized ChatRoomHttpClient getInstance() {
if (instance == null) {
instance = new ChatRoomHttpClient();
}
return instance;
}
private ChatRoomHttpClient() {
NimHttpClient.getInstance().init(DemoCache.getContext());
}
/**
* 向网易云信Demo应用服务器请求聊天室列表
*/
public void fetchChatRoomList(String appKey,
final ChatRoomHttpCallback<List<ChatRoomInfo>> callback) {
String url = DemoServers.chatRoomAPIServer() + API_NAME_CHAT_ROOM_LIST;
if (!DemoPrivatizationConfig.isPrivateDisable(DemoCache.getContext())) {
url = DemoPrivatizationConfig.getChatListRoomUrl(DemoCache.getContext());
}
Map<String, String> headers = new HashMap<>(1);
if (TextUtils.isEmpty(appKey)) {
appKey = readAppKey();
}
headers.put(HEADER_KEY_APP_KEY, appKey);
NimHttpClient client = NimHttpClient.getInstance();
client.execute(url, headers, null, false, (response, code, exception) -> {
if (code != 200 || exception != null) {
LogUtil.e(TAG, "fetchChatRoomList failed : code = " + code + ", errorMsg = " +
(exception != null ? exception.getMessage() : "null"));
if (callback != null) {
callback.onFailed(code, exception != null ? exception.getMessage() : "null");
}
return;
}
try {
// ret 0
JSONObject res = JSONObject.parseObject(response);
// res 1
int resCode = res.getIntValue(RESULT_KEY_RES);
if (resCode == RESULT_CODE_SUCCESS) {
// msg 1
JSONObject msg = res.getJSONObject(RESULT_KEY_MSG);
List<ChatRoomInfo> roomInfoList = null;
if (msg != null) {
// total 2
roomInfoList = new ArrayList<>(msg.getIntValue(RESULT_KEY_TOTAL));
// list 2
JSONArray rooms = msg.getJSONArray(RESULT_KEY_LIST);
for (int i = 0; i < rooms.size(); i++) {
// room 3
JSONObject room = rooms.getJSONObject(i);
ChatRoomInfo roomInfo = new ChatRoomInfo();
roomInfo.setName(room.getString(RESULT_KEY_NAME));
roomInfo.setCreator(room.getString(RESULT_KEY_CREATOR));
roomInfo.setValidFlag(room.getIntValue(RESULT_KEY_STATUS));
roomInfo.setAnnouncement(room.getString(RESULT_KEY_ANNOUNCEMENT));
roomInfo.setExtension(MessageHelper.getMapFromJsonString(
room.getString(RESULT_KEY_EXT)));
roomInfo.setRoomId(room.getString(RESULT_KEY_ROOM_ID));
roomInfo.setBroadcastUrl(room.getString(RESULT_KEY_BROADCAST_URL));
roomInfo.setOnlineUserCount(
room.getIntValue(RESULT_KEY_ONLINE_USER_COUNT));
roomInfoList.add(roomInfo);
}
// reply
callback.onSuccess(roomInfoList);
} else {
String errMsg = res.getString(RESULT_KEY_ERROR_MSG);
callback.onFailed(resCode, errMsg);
}
// reply
callback.onSuccess(roomInfoList);
} else {
callback.onFailed(resCode, null);
}
} catch (JSONException e) {
callback.onFailed(-1, e.getMessage());
} catch (Exception e) {
callback.onFailed(-2, e.getMessage());
}
});
}
/**
* 向网易云信Demo应用服务器请求聊天室列表
*/
public List<String> fetchChatRoomAddress(final String roomId, String appKey,
final String account) {
String url = DemoServers.chatRoomAPIServer() + API_NAME_CHAT_ROOM_ADDRESS;
Map<String, String> headers = new HashMap<>(1);
if (TextUtils.isEmpty(appKey)) {
appKey = readAppKey();
}
headers.put(HEADER_KEY_APP_KEY, appKey);
JSONObject jsonObject = new JSONObject();
jsonObject.put(REQUEST_KEY_ROOM_ID, roomId);
jsonObject.put(REQUEST_KEY_UID, account);
jsonObject.put(REQUEST_KEY_TYPE, 2);
HttpClientWrapper.HttpResult<String> result = com.netease.nim.uikit.common.http.HttpClientWrapper
.post(url, headers, jsonObject);
if (result.code == RESULT_CODE_SUCCESS && result.obj != null) {
try {
// ret 0
JSONObject res = JSONObject.parseObject(result.obj);
// res 1
int resCode = res.getIntValue(RESULT_KEY_RES);
if (resCode == RESULT_CODE_SUCCESS) {
// msg 1
JSONObject msg = res.getJSONObject(RESULT_KEY_MSG);
if (msg != null) {
// addr 2
JSONArray addressArray = msg.getJSONArray(RESULT_KEY_ADDR);
List<String> addressList = new ArrayList<>(addressArray.size());
for (int i = 0; i < addressArray.size(); i++) {
addressList.add(addressArray.getString(i)); // address 3
}
// reply
return addressList;
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
return null;
}
private String readAppKey() {
try {
ApplicationInfo appInfo = DemoCache.getContext().getPackageManager().getApplicationInfo(
DemoCache.getContext().getPackageName(), PackageManager.GET_META_DATA);
if (appInfo != null) {
return appInfo.metaData.getString("com.netease.nim.appKey");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
@@ -0,0 +1,34 @@
package cn.shangyu.gdxzExpert.netease.ui;
import android.annotation.SuppressLint;
import androidx.viewpager.widget.ViewPager;
import android.view.View;
/**
* Viewpager 页面切换动画,只支持3.0以上版本
* <p/>
* [-∞,-1]完全不可见
* [-1, 0]从不可见到完全可见
* [0,1]从完全可见到不可见
* [1,∞]完全不可见
* <p/>
* Created by doc on 15/1/6.
*/
public class FadeInOutPageTransformer implements ViewPager.PageTransformer {
@SuppressLint("NewApi")
@Override
public void transformPage(View page, float position) {
if (position < -1) {//页码完全不可见
page.setAlpha(0);
} else if (position < 0) {
page.setAlpha(1 + position);
} else if (position < 1) {
page.setAlpha(1 - position);
} else {
page.setAlpha(0);
}
}
}
@@ -0,0 +1,663 @@
/*
* Copyright (C) 2013 Andreas Stuetz <andreas.stuetz@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.shangyu.gdxzExpert.netease.ui;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.viewpager.widget.ViewPager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.netease.nim.uikit.common.ui.drop.DropFake;
import com.netease.nim.uikit.common.ui.drop.DropManager;
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
import java.util.Locale;
import cn.shangyu.gdxzExpert.R;
import cn.shangyu.gdxzExpert.netease.main.ReminderItem;
import cn.shangyu.gdxzExpert.netease.main.ReminderSettings;
public class PagerSlidingTabStrip extends HorizontalScrollView implements ViewPager.OnPageChangeListener {
// @formatter:off
private static final int[] ATTRS = new int[]{android.R.attr.textSize, android.R.attr.textColor};
// @formatter:on
private LinearLayout.LayoutParams tabViewLayoutParams;
private LinearLayout tabsContainer;
private ViewPager pager;
private int tabCount;
private int currentPosition = 0;
public int getCurrentPosition() {
return currentPosition;
}
private float currentPositionOffset = 0f;
private Paint rectPaint;
private Paint dividerPaint;
private int indicatorColor = 0xFF0888ff;
private int underlineColor = getResources().getColor(com.netease.nim.uikit.R.color.skin_page_tab_underline_color);// 0xFFD9D9D9;
private int dividerColor = 0x00000000;
private int checkedTextColor = com.netease.nim.uikit.R.color.color_blue_0888ff;
private int unCheckedTextColor = com.netease.nim.uikit.R.color.action_bar_tittle_color_555555;
private boolean textAllCaps = true;
private int scrollOffset = 52;
private int indicatorHeight = 3;
private int underlineHeight = 2;
private int dividerPadding = 12;
private int tabPadding = 0;
private int dividerWidth = 1;
private int lastScrollX = 0;
private Locale locale;
private OnTabClickListener onTabClickListener = null;
private OnTabDoubleTapListener onTabDoubleTapListener = null;
private OnCustomTabListener onCustomTabListener = null;
private boolean isFakeDropOpen = true;
public void setFakeDropOpen(boolean isFakeDropOpen) {
this.isFakeDropOpen = isFakeDropOpen;
}
public PagerSlidingTabStrip(Context context) {
this(context, null);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFillViewport(true);
setWillNotDraw(false);
tabsContainer = new LinearLayout(context);
tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addView(tabsContainer);
DisplayMetrics dm = getResources().getDisplayMetrics();
scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, underlineHeight, dm);
dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
// get system attrs (android:textSize and android:textColor)
TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
a.recycle();
// get custom attrs
a = context.obtainStyledAttributes(attrs, com.netease.nim.uikit.R.styleable.PagerSlidingTabStrip);
indicatorColor = a.getColor(com.netease.nim.uikit.R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor);
underlineColor = a.getColor(com.netease.nim.uikit.R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor);
dividerColor = a.getColor(com.netease.nim.uikit.R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor);
checkedTextColor = a.getResourceId(com.netease.nim.uikit.R.styleable.TwoTextView_ttLeftTextColor, com.netease.nim.uikit.R.color.color_blue_0888ff);
unCheckedTextColor = a.getResourceId(com.netease.nim.uikit.R.styleable.TwoTextView_ttLeftTextColor,
com.netease.nim.uikit.R.color.action_bar_tittle_color_555555);
indicatorHeight = a
.getDimensionPixelSize(com.netease.nim.uikit.R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight);
underlineHeight = a
.getDimensionPixelSize(com.netease.nim.uikit.R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight);
dividerPadding = a.getDimensionPixelSize(com.netease.nim.uikit.R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding);
tabPadding = a.getDimensionPixelSize(com.netease.nim.uikit.R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding);
scrollOffset = a.getDimensionPixelSize(com.netease.nim.uikit.R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset);
textAllCaps = a.getBoolean(com.netease.nim.uikit.R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);
a.recycle();
rectPaint = new Paint();
rectPaint.setAntiAlias(true);
rectPaint.setStyle(Style.FILL);
dividerPaint = new Paint();
dividerPaint.setAntiAlias(true);
dividerPaint.setStrokeWidth(dividerWidth);
tabViewLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);
if (locale == null) {
locale = getResources().getConfiguration().locale;
}
}
//
// OnPageChangeListener
//
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
currentPosition = position;
currentPositionOffset = positionOffset;
scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()));
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
scrollToChild(pager.getCurrentItem(), 0);
}
}
@Override
public void onPageSelected(int position) {
setChooseTabViewTextColor(position);
}
//
// OnPageChangeListener
//
public void setViewPager(ViewPager pager) {
this.pager = pager;
if (pager.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
notifyDataSetChanged();
}
public void notifyDataSetChanged() {
tabsContainer.removeAllViews();
tabCount = pager.getAdapter().getCount();
for (int i = 0; i < tabCount; i++) {
addTabView(i, pager.getAdapter().getPageTitle(i).toString());
}
// updateTabStyles();
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
currentPosition = pager.getCurrentItem();
setChooseTabViewTextColor(currentPosition);
scrollToChild(currentPosition, 0);
}
});
}
private void setChooseTabViewTextColor(int position) {
int childCount = tabsContainer.getChildCount();
LinearLayout tabView;
TextView textView;
for (int i = 0; i < childCount; ++i) {
tabView = (LinearLayout) tabsContainer.getChildAt(i);
textView = (TextView) tabView.findViewById(R.id.tab_title_label);
if (i == position) {
textView.setTextColor(getResources().getColor(checkedTextColor));
} else {
textView.setTextColor(getResources().getColor(unCheckedTextColor));
}
}
}
private void addTabView(final int position, String title) {
View tabView = null;
boolean screenAdaptation = false;
final LayoutInflater inflater = LayoutInflater.from(getContext());
if (this.onCustomTabListener != null) {
int tabResId = onCustomTabListener.getTabLayoutResId(position);
if (tabResId != 0) {
tabView = inflater.inflate(tabResId, null);
} else {
tabView = onCustomTabListener.getTabLayoutView(inflater, position);
}
screenAdaptation = onCustomTabListener.screenAdaptation();
}
if (tabView == null) {
tabView = inflater.inflate(R.layout.tab_layout_main, null);
}
TextView titleTV = ((TextView) tabView.findViewById(R.id.tab_title_label));
final boolean needAdaptation = ScreenUtil.density <= 1.5 && screenAdaptation;
final Resources resources = getContext().getResources();
if (titleTV != null) {
titleTV.setTextSize(TypedValue.COMPLEX_UNIT_PX, needAdaptation ? resources.getDimensionPixelSize(com.netease.nim.uikit.R.dimen.text_size_11) : resources.getDimensionPixelSize(com.netease.nim.uikit.R.dimen.text_size_15));
titleTV.setText(title);
}
final DropFake unreadTV = ((DropFake) tabView.findViewById(R.id.tab_new_msg_label));
if (unreadTV != null && isFakeDropOpen) {
unreadTV.setTouchListener(new DropFake.ITouchListener() {
@Override
public void onDown() {
DropManager.getInstance().setCurrentId(String.valueOf(position));
DropManager.getInstance().down(unreadTV, unreadTV.getText());
}
@Override
public void onMove(float curX, float curY) {
DropManager.getInstance().move(curX, curY);
}
@Override
public void onUp() {
DropManager.getInstance().up();
}
});
//unreadTV.setTextSize(TypedValue.COMPLEX_UNIT_PX, needAdaptation ? resources.getDimensionPixelSize(R.dimen.text_size_9) : resources.getDimensionPixelSize(R.dimen.text_size_12));
}
addTab(position, tabView);
}
private void addTab(final int position, View tab) {
tab.setFocusable(true);
tab.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (pager.getCurrentItem() == position && onTabClickListener != null) {
onTabClickListener.onCurrentTabClicked(position);
} else {
pager.setCurrentItem(position, true);
}
}
});
addTabDoubleTapListener(position, tab);
tab.setPadding(tabPadding, 0, tabPadding, 0);
tabsContainer.addView(tab, position, tabViewLayoutParams);
}
private void addTabDoubleTapListener(final int position, View tab) {
final GestureDetector gd = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
if (onTabDoubleTapListener != null)
onTabDoubleTapListener.onCurrentTabDoubleTap(position);
return true;
}
});
tab.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return gd.onTouchEvent(event);
}
});
}
public void updateTab(int index, ReminderItem item) {
LinearLayout tabView = (LinearLayout) tabsContainer.getChildAt(index);
ImageView indicatorView = (ImageView) tabView.findViewById(R.id.tab_new_indicator);
final DropFake unreadTV = ((DropFake) tabView.findViewById(R.id.tab_new_msg_label));
if (item == null || unreadTV == null || indicatorView == null) {
unreadTV.setVisibility(View.GONE);
indicatorView.setVisibility(View.GONE);
return;
}
int unread = item.unread();
boolean indicator = item.indicator();
unreadTV.setVisibility(unread > 0 ? View.VISIBLE : View.GONE);
indicatorView.setVisibility(indicator ? View.VISIBLE : View.GONE);
if (unread > 0) {
unreadTV.setText(String.valueOf(ReminderSettings.unreadMessageShowRule(unread)));
}
}
private void scrollToChild(int position, int offset) {
if (tabCount == 0) {
return;
}
int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset;
if (position > 0 || offset > 0) {
newScrollX -= scrollOffset;
}
if (newScrollX != lastScrollX) {
lastScrollX = newScrollX;
scrollTo(newScrollX, 0);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode() || tabCount == 0) {
return;
}
final int height = getHeight();
// draw underline
rectPaint.setColor(underlineColor);
canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint);
// draw indicator line
rectPaint.setColor(indicatorColor);
// default: line below current tab
View currentTab = tabsContainer.getChildAt(currentPosition);
float lineLeft = currentTab.getLeft();
float lineRight = currentTab.getRight();
// if there is an offset, start interpolating left and right coordinates between current and next tab
if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {
View nextTab = tabsContainer.getChildAt(currentPosition + 1);
final float nextTabLeft = nextTab.getLeft();
final float nextTabRight = nextTab.getRight();
lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);
}
canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint);
// draw divider
// dividerPaint.setColor(dividerColor);
// for (int i = 0; i < tabCount - 1; i++) {
// View tab = tabsContainer.getChildAt(i);
// canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
// }
}
public void setIndicatorColor(int indicatorColor) {
this.indicatorColor = indicatorColor;
invalidate();
}
public void setIndicatorColorResource(int resId) {
this.indicatorColor = getResources().getColor(resId);
invalidate();
}
public int getIndicatorColor() {
return this.indicatorColor;
}
public void setIndicatorHeight(int indicatorLineHeightPx) {
this.indicatorHeight = indicatorLineHeightPx;
invalidate();
}
public int getIndicatorHeight() {
return indicatorHeight;
}
public void setUnderlineColor(int underlineColor) {
this.underlineColor = underlineColor;
invalidate();
}
public void setUnderlineColorResource(int resId) {
this.underlineColor = getResources().getColor(resId);
invalidate();
}
public int getUnderlineColor() {
return underlineColor;
}
public void setDividerColor(int dividerColor) {
this.dividerColor = dividerColor;
invalidate();
}
public void setDividerColorResource(int resId) {
this.dividerColor = getResources().getColor(resId);
invalidate();
}
public int getDividerColor() {
return dividerColor;
}
public void setCheckedTextColorResource(int resId) {
this.checkedTextColor = resId;
invalidate();
}
public void setUnderlineHeight(int underlineHeightPx) {
this.underlineHeight = underlineHeightPx;
invalidate();
}
public int getUnderlineHeight() {
return underlineHeight;
}
public void setDividerPadding(int dividerPaddingPx) {
this.dividerPadding = dividerPaddingPx;
invalidate();
}
public int getDividerPadding() {
return dividerPadding;
}
public void setScrollOffset(int scrollOffsetPx) {
this.scrollOffset = scrollOffsetPx;
invalidate();
}
public int getScrollOffset() {
return scrollOffset;
}
public boolean isTextAllCaps() {
return textAllCaps;
}
public void setAllCaps(boolean textAllCaps) {
this.textAllCaps = textAllCaps;
}
public int getTabPaddingLeftRight() {
return tabPadding;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
// currentPosition = savedState.currentPosition;
currentPosition = 0;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPosition = currentPosition;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPosition;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPosition = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPosition);
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
public void setOnTabClickListener(OnTabClickListener onTabClickListener) {
this.onTabClickListener = onTabClickListener;
}
public void setOnTabDoubleTapListener(OnTabDoubleTapListener onTabDoubleTapListener) {
this.onTabDoubleTapListener = onTabDoubleTapListener;
}
/**
* must invoke before setViewPager
*
* @param onCustomTabListener
*/
public void setOnCustomTabListener(OnCustomTabListener onCustomTabListener) {
this.onCustomTabListener = onCustomTabListener;
}
/**
* TAB 的点击监�?
*/
public interface OnTabClickListener {
public void onCurrentTabClicked(int position);
}
/**
* TAB 的双击监�?
*/
public interface OnTabDoubleTapListener {
public void onCurrentTabDoubleTap(int position);
}
/**
* 获取每个TAB的自定义布局
*/
public static class OnCustomTabListener {
/**
* �?要自定义TAB的布�?�?
* 重写该方法,返回对应的layout id
*
* @param position
* @return
*/
public int getTabLayoutResId(int position) {
return 0;
}
/**
* �?要自定义TAB的布�?
* 重写该方法,直接返回对应的view
*
* @param inflater
* @param position
* @return
*/
public View getTabLayoutView(LayoutInflater inflater, int position) {
return null;
}
/**
* 是否�?要小屏幕适配,只在存在多个tab,且tab的布�?较紧时�?�配,现在只用于主界面
*
* @return
*/
public boolean screenAdaptation() {
return false;
}
}
}
@@ -0,0 +1,130 @@
package cn.shangyu.gdxzExpert.netease.ui;
import android.content.Context;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.netease.nim.uikit.common.fragment.TabFragment;
public abstract class SlidingTabPagerAdapter extends FragmentPagerAdapter implements TabFragment.State,
PagerSlidingTabStrip.OnTabClickListener, PagerSlidingTabStrip.OnTabDoubleTapListener {
protected final TabFragment[] fragments;
protected final Context context;
private final ViewPager pager;
public abstract int getCacheCount();
private int lastPostion = 0;
public SlidingTabPagerAdapter(FragmentManager fm, int count, Context context, ViewPager pager) {
super(fm);
this.fragments = new TabFragment[count];
this.context = context;
this.pager = pager;
lastPostion = 0;
}
@Override
public TabFragment getItem(int pos) {
return fragments[pos];
}
@Override
public abstract int getCount();
@Override
public abstract CharSequence getPageTitle(int position);
@Override
public boolean isCurrent(TabFragment f) {
// FROM PAGER
int current = pager.getCurrentItem();
// TRAVEL
for (int index = 0; index < fragments.length; index++) {
// CATCH
if (f == fragments[index]) {
// MATCH
if (index == current) {
return true;
}
}
}
// ANY PROBLEM
return false;
}
public void onPageSelected(int position) {
TabFragment fragment = getFragmentByPosition(position);
// INSTANCE
if (fragment == null) {
return;
}
fragment.onCurrent();
onLeave(position);
}
private void onLeave(int position) {
TabFragment fragment = getFragmentByPosition(lastPostion);
lastPostion = position;
// INSTANCE
if (fragment == null) {
return;
}
fragment.onLeave();
}
public void onPageScrolled(int position) {
TabFragment fragment = getFragmentByPosition(position);
// INSTANCE
if (fragment == null) {
return;
}
fragment.onCurrentScrolled();
onLeave(position);
}
private TabFragment getFragmentByPosition(int position) {
// IDX
if (position < 0 || position >= fragments.length) {
return null;
}
return fragments[position];
}
@Override
public void onCurrentTabClicked(int position) {
TabFragment fragment = getFragmentByPosition(position);
// INSTANCE
if (fragment == null) {
return;
}
fragment.onCurrentTabClicked();
}
@Override
public void onCurrentTabDoubleTap(int position) {
TabFragment fragment = getFragmentByPosition(position);
// INSTANCE
if (fragment == null) {
return;
}
fragment.onCurrentTabDoubleTap();
}
}
@@ -0,0 +1,355 @@
package cn.shangyu.gdxzExpert.netease.uinfo;
import static cn.shangyu.gdxzExpert.utils.Url.urlHtml;
import android.text.TextUtils;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.business.session.constant.Extras;
import com.netease.nim.uikit.business.team.helper.SuperTeamHelper;
import com.netease.nim.uikit.business.team.helper.TeamHelper;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.netease.nimlib.sdk.uinfo.UserService;
import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;
import com.netease.nimlib.sdk.uinfo.model.UserInfo;
import java.util.HashMap;
import java.util.Map;
import cn.shangyu.gdxzExpert.ecdemo.storage.PatientSqlManager;
import cn.shangyu.gdxzExpert.ecdemo.ui.chatting.model.PatientModel;
import cn.shangyu.gdxzExpert.utils.Constant;
import cn.shangyu.gdxzExpert.utils.SharePrefUtil;
import cn.shangyu.gdxzExpert.utils.StringUtil;
import cn.shangyu.gdxzExpert.utils.UIUtils;
import cn.shangyu.gdxzExpert.utils.Url;
public class UserInfoHelper {
// 获取用户显示在标题栏和最近联系人中的名字
public static String getUserTitleName(String id, SessionTypeEnum sessionType) {
if (sessionType == SessionTypeEnum.P2P) {
if (NimUIKit.getAccount().equals(id)) {
return "我的电脑";
} else {
return getUserDisplayName(id);
}
} else if (sessionType == SessionTypeEnum.Team) {
return TeamHelper.getTeamName(id);
} else if (sessionType == SessionTypeEnum.Ysf) {
return "我的客服";
}
return id;
}
/**
* @param account 用户帐号
* @return
*/
public static String getUserDisplayName(String account) {
if(account==null)
return null;
// if(!account.contains("#"))
// {
// return getUserName(account);
// }
// else
// {
// return getUserName(account.split("#")[1]);
// }
if(!account.contains("#"))
account= Constant.Patient_AppKey+account;
PatientModel Pm= PatientSqlManager.getPatientInfo(account);
if (Pm != null && Pm.getRealName() != null) {
return Pm.getRealName();
}
else if(Pm != null && Pm.getNickName() != null)
{
return Pm.getNickName();
}
else {
return getUserName(account.split("#")[1]);
}
}
/**
* @param account 用户帐号
* @return 用户头像
*/
public static String getUserDisplayPhoto(String account) {
if(account==null)
return "null";
// if(account.contains("#"))
// {
// account=account.split("#")[1];
// }
// account=account.toLowerCase();
// if(account.equals(NimUIKit.getAccount())) {
// return urlHtml + SharePrefUtil.getString(UIUtils.getContext(), "photo", "");
// }
// UserInfo userInfo = NimUIKit.getUserInfoProvider().getUserInfo(account);
// if (userInfo != null && !TextUtils.isEmpty(userInfo.getAvatar())) {
//
// return userInfo.getAvatar();
// }
// else {
// if(account.equals(NimUIKit.getAccount())) {
// return urlHtml + SharePrefUtil.getString(UIUtils.getContext(), "photo", "");
// }
// else
// {
// if(!account.contains("#"))
// account= Constant.Patient_AppKey+account;
// PatientModel Pm= PatientSqlManager.getPatientInfo(account);
// if (Pm != null && Pm.getPhoto() != null) {
// return Url.urlHtml+Pm.getPhoto();
// }
// else {
// return account;
// }
// }
// }
if(account.equals(NimUIKit.getAccount())) {
return urlHtml + SharePrefUtil.getString(UIUtils.getContext(), "photo", "");
}
else
{
if(!account.contains("#"))
account=Constant.Patient_AppKey+account;
PatientModel Pm= PatientSqlManager.getPatientInfo(account);
if (Pm != null && Pm.getPhoto() != null) {
return Url.urlHtml+Pm.getPhoto();
}
else {
return null;
}
}
}
/**
* 获取消息发送者的展示名称,优先级序列:备注>群昵称>用户名>账号
*
* @param account 用户账号
* @param sessionType 所处会话的类型
* @param sessionId 所处会话的ID
* @return 发送者的展示名称
*/
public static String getUserDisplayNameInSession(String account, SessionTypeEnum sessionType, String sessionId) {
if (TextUtils.isEmpty(account)) {
return "";
}
// 备注
String alias = NimUIKit.getContactProvider().getAlias(account);
if (!TextUtils.isEmpty(alias)) {
return alias;
}
// 群昵称
String teamNick = null;
if (sessionType == SessionTypeEnum.Team) {
teamNick = TeamHelper.getTeamNick(sessionId, account);
} else if (sessionType == SessionTypeEnum.SUPER_TEAM) {
teamNick = SuperTeamHelper.getTeamNick(sessionId, account);
}
if (!TextUtils.isEmpty(teamNick)) {
return teamNick;
}
// 用户名
UserInfo userInfo = NimUIKit.getUserInfoProvider().getUserInfo(account);
if (userInfo != null && !TextUtils.isEmpty(userInfo.getName())) {
return userInfo.getName();
}
// 账号
return account;
}
// 获取用户原本的昵称
public static String getUserName(String account) {
// Log.d("gdxzname","account "+account);
if(account==null)
return "null";
if(account.contains("#"))
{
account=account.split("#")[1];
}
account=account.toLowerCase();
RecentContact recentContact= NIMClient.getService(MsgService.class).queryRecentContact(account, SessionTypeEnum.P2P);
if(recentContact!=null)
{
Map<String, Object> ext = recentContact.getExtension();
// Log.d("gdxzname","nicknemerecentext "+ext);
if(ext!=null)
{
if(ext.get(Extras.EXTRA_GDXZ_NICKNAME)!=null)
{
String nickneme=ext.get(Extras.EXTRA_GDXZ_NICKNAME).toString();
if(!StringUtil.isEmpty(nickneme))
{
// Log.d("gdxzname","nicknemerecent "+nickneme);
return nickneme;
}
}
}
}
IMMessage im =NIMClient.getService(MsgService.class).queryLastMessage(account, SessionTypeEnum.P2P);
// Log.d("gdxzname","im ");
if(im!=null)
{
Map<String, Object> ext = im.getRemoteExtension();
if(ext!=null)
{
if(ext.get(Extras.EXTRA_GDXZ_NICKNAME)!=null)
{
String nickneme=ext.get(Extras.EXTRA_GDXZ_NICKNAME).toString();
// Log.d("gdxzname","nicknemehreh "+nickneme);
if(!StringUtil.isEmpty(nickneme))
{
return nickneme;
}
}
}
}
NimUserInfo userInfo = NIMClient.getService(UserService.class).getUserInfo(account);
// Log.d("gdxzname","userInfo "+userInfo);
// UserInfo userInfo1= NimUIKit.getUserInfoProvider().getUserInfo(account);
// Log.d("gdxzname","userInfo1 "+userInfo1);
if (userInfo != null && !TextUtils.isEmpty(userInfo.getName())) {
// Log.d("gdxzname","name "+userInfo.getName());
return userInfo.getName();
}
// else {
// if(!account.contains("#"))
// account=Constant.Patient_AppKey+account;
// PatientModel Pm= PatientSqlManager.getPatientInfo(account);
// if (Pm != null && Pm.getRealName() != null) {
// return Pm.getRealName();
// }
// else if(Pm != null && Pm.getNickName() != null)
// {
// return Pm.getNickName();
// }
// else {
//// return getUserName(account.split("#")[1]);
// return account;
//
// }
return account;
// }
}
/**
* @param account 账号
* @param selfNameDisplay 如果是自己,则显示内容
* @return
*/
public static String getUserDisplayNameEx(String account, String selfNameDisplay) {
if (account.equals(NimUIKit.getAccount())) {
return selfNameDisplay;
}
return getUserDisplayName(account);
}
/**
* @param account 对方的id/群id
* @param sessionType 会话类型
*/
public static Boolean isPatient(java.lang.String account, SessionTypeEnum sessionType)
{
if(account.contains("#"))
{
account=account.split("#")[1];
}
account=account.toLowerCase();
IMMessage im =NIMClient.getService(MsgService.class).queryLastMessage(account, sessionType);
if(im==null)
{
return false;
}
// Log.d("gdxzname","imgetContent "+im.getContent());
Map<String, Object> ext = im.getRemoteExtension();
// Log.d("gdxzname","ext "+ext.toString());
if(ext!=null)
{
if(ext.get(Extras.EXTRA_GDXZ_TYPE)!=null)
{
String type=ext.get(Extras.EXTRA_GDXZ_TYPE).toString();
// Log.d("gdxzname","type "+type);
switch (type)
{
case "general":
return true;
case "consult":
return false;
}
}
}
return false;
}
public static void updatePatientInfo(String account, SessionTypeEnum sessionType, String nikename)
{
if(account==null)
return ;
if(account.contains("#"))
{
account=account.split("#")[1];
}
account=account.toLowerCase();
Map<String, Object> ext;
IMMessage im = NIMClient.getService(MsgService.class).queryLastMessage(account, sessionType);
if(im==null||im.getRemoteExtension()==null)
{
// Log.d("gdxzname","nolast ");
ext=new HashMap<>();
// return;
}
else
{
ext= im.getRemoteExtension();
}
ext.put(Extras.EXTRA_GDXZ_NICKNAME,nikename);
// im.setLocalExtension(ext);
// NIMClient.getService(MsgService.class).updateIMMessage(im);
RecentContact recentContact= NIMClient.getService(MsgService.class).queryRecentContact(account, sessionType);
if(recentContact==null)
{
return;
}
recentContact.setExtension(ext);
NIMClient.getService(MsgService.class).updateRecent(recentContact);
// boolean isMyFriend = NIMClient.getService(FriendService.class).isMyFriend(account);
// Log.d("gdxzname","nicknemerecentext1 "+recentContact.getExtension());
}
}
@@ -0,0 +1,33 @@
package cn.shangyu.gdxzExpert.netease.util;
/**
* Created by winnie on 2017/12/21.
*/
public class LogHelper {
public static void init() {
// AVChatKit.setiLogUtil(new ILogUtil() {
// @Override
// public void ui(String msg) {
// LogUtil.ui(msg);
// }
//
// @Override
// public void e(String tag, String msg) {
// LogUtil.e(tag, msg);
// }
//
// @Override
// public void i(String tag, String msg) {
// LogUtil.i(tag, msg);
// }
//
// @Override
// public void d(String tag, String msg) {
// LogUtil.d(tag, msg);
// }
// });
}
}
@@ -0,0 +1,51 @@
package cn.shangyu.gdxzExpert.netease.util.crash;
import android.content.Context;
import java.lang.Thread.UncaughtExceptionHandler;
public class AppCrashHandler {
private Context context;
private UncaughtExceptionHandler uncaughtExceptionHandler;
private static AppCrashHandler instance;
private AppCrashHandler(Context context) {
this.context = context;
// get default
uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
// install
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, final Throwable ex) {
// save log
saveException(ex, true);
// uncaught
uncaughtExceptionHandler.uncaughtException(thread, ex);
}
});
}
public static AppCrashHandler getInstance(Context mContext) {
if (instance == null) {
instance = new AppCrashHandler(mContext);
}
return instance;
}
public final void saveException(Throwable ex, boolean uncaught) {
CrashSaver.save(context, ex, uncaught);
}
public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
if (handler != null) {
this.uncaughtExceptionHandler = handler;
}
}
}
@@ -0,0 +1,122 @@
package cn.shangyu.gdxzExpert.netease.util.crash;
import android.content.Context;
import android.text.TextUtils;
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.string.MD5;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
class CrashSaver {
public static final void save(Context context, Throwable ex,
boolean uncaught) {
if (!StorageUtil.isExternalStorageExist()) {// 如果没有sdcard,则不存储
return;
}
Writer writer = null;
PrintWriter printWriter = null;
String stackTrace = "";
try {
writer = new StringWriter();
printWriter = new PrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
stackTrace = writer.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (printWriter != null) {
printWriter.close();
}
}
String signature = stackTrace.replaceAll("\\([^\\(]*\\)", "");
String filename = MD5.getStringMD5(signature);
if (TextUtils.isEmpty(filename)) {
return;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
String timestamp = sdf.format(date);
BufferedWriter mBufferedWriter = null;
try {
File mFile = new File(StorageUtil.getWritePath(
filename + ".crashlog", StorageType.TYPE_LOG));
File pFile = mFile.getParentFile();
if (!pFile.exists()) {// 如果文件夹不存在,则先创建文件夹
pFile.mkdirs();
}
int count = 1;
if (mFile.exists()) {
LineNumberReader reader = null;
try {
reader = new LineNumberReader(new FileReader(mFile));
String line = reader.readLine();
if (line.startsWith("count")) {
int index = line.indexOf(":");
if (index != -1) {
String count_str = line.substring(++index);
if (count_str != null) {
count_str = count_str.trim();
count = Integer.parseInt(count_str);
count++;
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
mFile.delete();
}
mFile.createNewFile();
mBufferedWriter = new BufferedWriter(new FileWriter(mFile, true));// 追加模式写文件
mBufferedWriter.append(CrashSnapshot.snapshot(context, uncaught, timestamp, stackTrace, count));
mBufferedWriter.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (mBufferedWriter != null) {
try {
mBufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More