私聊改造:输入体验优化
This commit is contained in:
@@ -676,7 +676,6 @@
|
|||||||
android:label="单聊界面"
|
android:label="单聊界面"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/AppTheme.NoActionBar"
|
|
||||||
android:windowSoftInputMode="stateHidden|adjustResize" />
|
android:windowSoftInputMode="stateHidden|adjustResize" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.im.avtivity.AddBlackListActivity"
|
android:name=".ui.im.avtivity.AddBlackListActivity"
|
||||||
@@ -952,10 +951,12 @@
|
|||||||
<!-- 房间内私聊 -->
|
<!-- 房间内私聊 -->
|
||||||
<activity
|
<activity
|
||||||
android:name=".room_chat.activity.NimRoomP2PMessageActivity"
|
android:name=".room_chat.activity.NimRoomP2PMessageActivity"
|
||||||
android:theme="@style/room_message_activity" />
|
android:theme="@style/room_message_activity"
|
||||||
|
android:windowSoftInputMode="stateHidden|adjustResize" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".room_chat.activity.RoomMsgActivity"
|
android:name=".room_chat.activity.RoomMsgActivity"
|
||||||
android:theme="@style/room_message_activity" />
|
android:theme="@style/room_message_activity"
|
||||||
|
android:windowSoftInputMode="stateHidden|adjustNothing" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".room_chat.activity.RoomNewbieActivity"
|
android:name=".room_chat.activity.RoomNewbieActivity"
|
||||||
android:theme="@style/room_message_activity" />
|
android:theme="@style/room_message_activity" />
|
||||||
|
@@ -0,0 +1,44 @@
|
|||||||
|
package com.mango.moshen.ui.im;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.effective.android.panel.PanelSwitchHelper;
|
||||||
|
|
||||||
|
public class AutoHidePanelRecyclerView extends RecyclerView {
|
||||||
|
|
||||||
|
PanelSwitchHelper panelSwitchHelper;
|
||||||
|
|
||||||
|
public void setPanelSwitchHelper(PanelSwitchHelper panelSwitchHelper) {
|
||||||
|
this.panelSwitchHelper = panelSwitchHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutoHidePanelRecyclerView(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutoHidePanelRecyclerView(Context context, @Nullable AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public AutoHidePanelRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
setLayoutManager(new LinearLayoutManager(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent e) {
|
||||||
|
if (e != null && e.getAction() != MotionEvent.ACTION_CANCEL) {
|
||||||
|
if (panelSwitchHelper != null) {
|
||||||
|
panelSwitchHelper.hookSystemBackByPanelSwitcher();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.onTouchEvent(e);
|
||||||
|
}
|
||||||
|
}
|
@@ -7,7 +7,9 @@ import com.netease.nim.uikit.api.model.contact.ContactEventListener;
|
|||||||
import com.netease.nim.uikit.api.model.session.SessionCustomization;
|
import com.netease.nim.uikit.api.model.session.SessionCustomization;
|
||||||
import com.netease.nim.uikit.api.model.session.SessionEventListener;
|
import com.netease.nim.uikit.api.model.session.SessionEventListener;
|
||||||
import com.netease.nim.uikit.business.session.actions.BaseAction;
|
import com.netease.nim.uikit.business.session.actions.BaseAction;
|
||||||
|
import com.netease.nim.uikit.business.session.actions.CameraAction;
|
||||||
import com.netease.nim.uikit.business.session.actions.ImageAction;
|
import com.netease.nim.uikit.business.session.actions.ImageAction;
|
||||||
|
import com.netease.nim.uikit.business.session.actions.PhotoAction;
|
||||||
import com.netease.nimlib.sdk.msg.model.IMMessage;
|
import com.netease.nimlib.sdk.msg.model.IMMessage;
|
||||||
import com.mango.moshen.community.holder.DynamicSysHolder;
|
import com.mango.moshen.community.holder.DynamicSysHolder;
|
||||||
import com.mango.moshen.community.im.WorldDynamicShareViewHolder;
|
import com.mango.moshen.community.im.WorldDynamicShareViewHolder;
|
||||||
@@ -116,10 +118,11 @@ public class ImInitHelper {
|
|||||||
private void initP2PSessionCustomization() {
|
private void initP2PSessionCustomization() {
|
||||||
SessionCustomization sessionCustomization = new SessionCustomization();
|
SessionCustomization sessionCustomization = new SessionCustomization();
|
||||||
ArrayList<BaseAction> actions = new ArrayList<>();
|
ArrayList<BaseAction> actions = new ArrayList<>();
|
||||||
actions.add(new ImageAction());
|
actions.add(new PhotoAction());
|
||||||
|
actions.add(new CameraAction());
|
||||||
actions.add(new GiftAction());
|
actions.add(new GiftAction());
|
||||||
sessionCustomization.actions = actions;
|
sessionCustomization.actions = actions;
|
||||||
sessionCustomization.withSticker = true;
|
sessionCustomization.withSticker = false;
|
||||||
NimUIKit.setCommonP2PSessionCustomization(sessionCustomization);
|
NimUIKit.setCommonP2PSessionCustomization(sessionCustomization);
|
||||||
|
|
||||||
// 语音派对
|
// 语音派对
|
||||||
|
878
app/src/main/java/com/mango/moshen/ui/im/InputPanel.java
Normal file
878
app/src/main/java/com/mango/moshen/ui/im/InputPanel.java
Normal file
@@ -0,0 +1,878 @@
|
|||||||
|
package com.mango.moshen.ui.im;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Color;
|
||||||
|
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.KeyEvent;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
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 com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.effective.android.panel.PanelSwitchHelper;
|
||||||
|
import com.effective.android.panel.interfaces.PanelHeightMeasurer;
|
||||||
|
import com.effective.android.panel.interfaces.listener.OnPanelChangeListener;
|
||||||
|
import com.effective.android.panel.view.panel.IPanelView;
|
||||||
|
import com.effective.android.panel.view.panel.PanelView;
|
||||||
|
import com.mango.moshen.R;
|
||||||
|
import com.mango.moshen.ui.im.actions.GiftAction;
|
||||||
|
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||||
|
import com.mango.xchat_android_library.utils.SizeUtils;
|
||||||
|
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.actions.CameraAction;
|
||||||
|
import com.netease.nim.uikit.business.session.actions.PhotoAction;
|
||||||
|
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.event.ActiveEvent;
|
||||||
|
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.session.module.input.NimAudioChatEvent;
|
||||||
|
import com.netease.nim.uikit.common.antispam.AntiSpamEvent;
|
||||||
|
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper;
|
||||||
|
import com.netease.nim.uikit.common.util.AntiSpamUtil;
|
||||||
|
import com.netease.nim.uikit.common.util.log.LogUtil;
|
||||||
|
import com.netease.nim.uikit.common.util.string.StringUtil;
|
||||||
|
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
|
||||||
|
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 org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 底部文本编辑,语音等模块
|
||||||
|
* 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 = 0;
|
||||||
|
|
||||||
|
protected Container container;
|
||||||
|
protected View view;
|
||||||
|
protected Handler uiHandler;
|
||||||
|
|
||||||
|
protected EditText messageEditText;// 文本消息编辑框
|
||||||
|
protected Button audioRecordBtn; // 录音按钮
|
||||||
|
protected View audioAnimLayout; // 录音动画布局
|
||||||
|
protected FrameLayout textAudioSwitchLayout; // 切换文本,语音按钮布局
|
||||||
|
protected View switchToTextButtonInInputBar;// 文本消息选择按钮
|
||||||
|
protected View switchToAudioButtonInInputBar;// 语音消息选择按钮
|
||||||
|
protected View sendMessageButtonInInputBar;// 发送消息按钮
|
||||||
|
protected View emojiButtonInInputBar;// 发送消息按钮
|
||||||
|
protected View messageInputBar;
|
||||||
|
// 表情
|
||||||
|
protected EmoticonPickerView emoticonPickerView; // 贴图表情控件
|
||||||
|
// 语音
|
||||||
|
protected AudioRecorder audioMessageHelper;
|
||||||
|
private AutoHidePanelRecyclerView messageListView;
|
||||||
|
private SessionCustomization customization;
|
||||||
|
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; // 是否显示键盘
|
||||||
|
private boolean isTextAudioSwitchShow; // 是否展示左侧语音按钮
|
||||||
|
// adapter
|
||||||
|
private List<BaseAction> actions;
|
||||||
|
// data
|
||||||
|
private long typingTime = 0;
|
||||||
|
private TextWatcher aitTextWatcher;
|
||||||
|
private volatile boolean disable;
|
||||||
|
private boolean isChat;
|
||||||
|
private PanelSwitchHelper mHelper;
|
||||||
|
private final Runnable showTextRunnable = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
showInputMethod(messageEditText);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private ImageView ivImage;
|
||||||
|
private ImageView ivCamera;
|
||||||
|
private ImageView ivGift;
|
||||||
|
/**
|
||||||
|
* ************************* 键盘布局切换 *******************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
private final 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) {
|
||||||
|
switchToAudioLayout();
|
||||||
|
} else if (v == ivCamera) {
|
||||||
|
for (BaseAction action : actions) {
|
||||||
|
if (action instanceof CameraAction) {
|
||||||
|
action.onClick();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mHelper.resetState();
|
||||||
|
} else if (v == ivGift) {
|
||||||
|
|
||||||
|
ivGift.postDelayed(() -> {
|
||||||
|
for (BaseAction action : actions) {
|
||||||
|
if (action instanceof GiftAction) {
|
||||||
|
action.onClick();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, !mHelper.isResetState() ? 300 : 0);
|
||||||
|
mHelper.resetState();
|
||||||
|
} else if (v == ivImage) {
|
||||||
|
for (BaseAction action : actions) {
|
||||||
|
if (action instanceof PhotoAction) {
|
||||||
|
action.onClick();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mHelper.resetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上滑取消录音判断
|
||||||
|
private static boolean isCancelled(View view, MotionEvent event) {
|
||||||
|
int[] location = new int[2];
|
||||||
|
view.getLocationOnScreen(location);
|
||||||
|
|
||||||
|
return event.getRawX() < location[0] || event.getRawX() > location[0] + view.getWidth()
|
||||||
|
|| event.getRawY() < location[1] - 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPause() {
|
||||||
|
// 停止录音
|
||||||
|
if (audioMessageHelper != null) {
|
||||||
|
onEndAudioRecord(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDestroy() {
|
||||||
|
// release
|
||||||
|
if (audioMessageHelper != null) {
|
||||||
|
audioMessageHelper.destroyAudioRecorder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean collapse(boolean immediately) {
|
||||||
|
boolean respond = !mHelper.isResetState();
|
||||||
|
mHelper.resetState();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disable) {
|
||||||
|
disableButtons();
|
||||||
|
}
|
||||||
|
if (mHelper == null) {
|
||||||
|
mHelper = new PanelSwitchHelper.Builder(container.activity)
|
||||||
|
//可选
|
||||||
|
.addKeyboardStateListener((visible, height) -> {
|
||||||
|
Log.d(TAG, "系统键盘是否可见 : " + visible + " 高度为:" + height);
|
||||||
|
})
|
||||||
|
//可选
|
||||||
|
.addEditTextFocusChangeListener((view, hasFocus) -> {
|
||||||
|
Log.d(TAG, "输入框是否获得焦点 : " + hasFocus);
|
||||||
|
})
|
||||||
|
//可选
|
||||||
|
.addViewClickListener(view -> {
|
||||||
|
if (view == null) return;
|
||||||
|
if (view.getId() == R.id.emoji_button) {
|
||||||
|
switchToTextLayout(false);
|
||||||
|
}
|
||||||
|
Log.d(TAG, "点击了View : " + view);
|
||||||
|
})
|
||||||
|
//可选
|
||||||
|
.addPanelChangeListener(new OnPanelChangeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onKeyboard() {
|
||||||
|
Log.d(TAG, "唤起系统输入法");
|
||||||
|
container.proxy.onInputPanelExpand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNone() {
|
||||||
|
Log.d(TAG, "隐藏所有面板");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPanel(IPanelView view) {
|
||||||
|
Log.d(TAG, "唤起面板 : " + view);
|
||||||
|
container.proxy.onInputPanelExpand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPanelSizeChange(IPanelView panelView, boolean portrait, int oldWidth, int oldHeight, int width, int height) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.addPanelHeightMeasurer(new PanelHeightMeasurer() {
|
||||||
|
@Override
|
||||||
|
public boolean synchronizeKeyboardHeight() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTargetPanelDefaultHeight() {
|
||||||
|
return ScreenUtil.dip2px(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPanelTriggerId() {
|
||||||
|
return R.id.iv_image;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.addPanelHeightMeasurer(new PanelHeightMeasurer() {
|
||||||
|
@Override
|
||||||
|
public boolean synchronizeKeyboardHeight() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTargetPanelDefaultHeight() {
|
||||||
|
return ScreenUtil.dip2px(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPanelTriggerId() {
|
||||||
|
return R.id.emoji_button;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.logTrack(true)//output log
|
||||||
|
.build();
|
||||||
|
|
||||||
|
messageListView.setPanelSwitchHelper(mHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
||||||
|
messageInputBar = view.findViewById(R.id.textMessageLayout);
|
||||||
|
switchToTextButtonInInputBar = view.findViewById(R.id.buttonTextMessage);
|
||||||
|
switchToAudioButtonInInputBar = view.findViewById(R.id.buttonAudioMessage);
|
||||||
|
emojiButtonInInputBar = view.findViewById(R.id.emoji_button);
|
||||||
|
sendMessageButtonInInputBar = view.findViewById(R.id.buttonSendMessage);
|
||||||
|
messageEditText = view.findViewById(R.id.editTextMessage);
|
||||||
|
|
||||||
|
// 语音
|
||||||
|
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);
|
||||||
|
emoticonPickerView.show(this);
|
||||||
|
|
||||||
|
// 显示录音按钮
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
messageListView = view.findViewById(R.id.messageListView);
|
||||||
|
ivImage = view.findViewById(R.id.iv_image);
|
||||||
|
ivCamera = view.findViewById(R.id.iv_camera);
|
||||||
|
ivGift = view.findViewById(R.id.iv_gift);
|
||||||
|
ivCamera.setOnClickListener(clickListener);
|
||||||
|
ivGift.setOnClickListener(clickListener);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disableButtons() {
|
||||||
|
if (messageEditText != null && audioRecordBtn != null &&
|
||||||
|
switchToTextButtonInInputBar != null &&
|
||||||
|
switchToAudioButtonInInputBar != null &&
|
||||||
|
emojiButtonInInputBar != null) {
|
||||||
|
messageEditText.setEnabled(false);
|
||||||
|
messageEditText.setHint("禁言中,快找管理员解除禁言吧!");
|
||||||
|
messageEditText.setHintTextColor(Color.parseColor("#999999"));
|
||||||
|
audioRecordBtn.setEnabled(false);
|
||||||
|
switchToTextButtonInInputBar.setEnabled(false);
|
||||||
|
switchToAudioButtonInInputBar.setEnabled(false);
|
||||||
|
emojiButtonInInputBar.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
setDisable(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisable(boolean disable) {
|
||||||
|
this.disable = disable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initInputBarListener() {
|
||||||
|
switchToTextButtonInInputBar.setOnClickListener(clickListener);
|
||||||
|
switchToAudioButtonInInputBar.setOnClickListener(clickListener);
|
||||||
|
sendMessageButtonInInputBar.setOnClickListener(clickListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initTextEdit() {
|
||||||
|
messageEditText.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
|
messageEditText.setImeOptions(EditorInfo.IME_ACTION_SEND);
|
||||||
|
messageEditText.setOnEditorActionListener((v, actionId, event) -> {
|
||||||
|
//当actionId == XX_SEND 或者 XX_DONE时都触发
|
||||||
|
//或者event.getKeyCode == ENTER 且 event.getAction == ACTION_DOWN时也触发
|
||||||
|
//注意,这是一定要判断event != null。因为在某些输入法上会返回null。
|
||||||
|
if (actionId == EditorInfo.IME_ACTION_SEND
|
||||||
|
|| actionId == EditorInfo.IME_ACTION_DONE
|
||||||
|
|| (event != null && KeyEvent.KEYCODE_ENTER == event.getKeyCode() && KeyEvent.ACTION_DOWN == event.getAction())) {
|
||||||
|
//处理事件
|
||||||
|
onTextMessageSendButtonPressed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
messageEditText.setOnFocusChangeListener((v, 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(Math.min(s.length(), editEnd));
|
||||||
|
messageEditText.addTextChangedListener(this);
|
||||||
|
|
||||||
|
if (aitTextWatcher != null) {
|
||||||
|
aitTextWatcher.afterTextChanged(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
sendTypingCommand();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 不展示右侧按钮时需要添加edit间距
|
||||||
|
if (!isTextAudioSwitchShow) {
|
||||||
|
try {
|
||||||
|
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) messageEditText.getLayoutParams();
|
||||||
|
layoutParams.setMarginStart(SizeUtils.dp2px(view.getContext(), 12));
|
||||||
|
messageEditText.requestLayout();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送“正在输入”通知
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击edittext,切换键盘和更多布局
|
||||||
|
private void switchToTextLayout(boolean needShowInput) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送文本消息
|
||||||
|
private void onTextMessageSendButtonPressed() {
|
||||||
|
String text = messageEditText.getText().toString();
|
||||||
|
if (TextUtils.isEmpty(text.trim())) return;
|
||||||
|
EventBus.getDefault().post(new ActiveEvent());
|
||||||
|
IMMessage textMessage = createTextMessage(text);
|
||||||
|
if (AntiSpamUtil.checkLocalAntiSpam(textMessage)) {
|
||||||
|
EventBus.getDefault().post(new AntiSpamEvent());
|
||||||
|
} else {
|
||||||
|
if (container.proxy.sendMessage(textMessage)) {
|
||||||
|
restoreText(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IMMessage createTextMessage(String text) {
|
||||||
|
return MessageBuilder.createTextMessage(container.account, container.sessionType, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换成音频,收起键盘,按钮切换成键盘
|
||||||
|
private void switchToAudioLayout() {
|
||||||
|
if (!isChat) {
|
||||||
|
SingleToastUtil.showToast("等级不够");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.e(TAG, "switchToAudioLayout: ");
|
||||||
|
NimAudioChatEvent event = new NimAudioChatEvent();
|
||||||
|
event.setSuccess(o -> {
|
||||||
|
messageEditText.setVisibility(View.GONE);
|
||||||
|
audioRecordBtn.setVisibility(View.VISIBLE);
|
||||||
|
hideInputMethod();
|
||||||
|
switchToAudioButtonInInputBar.setVisibility(View.GONE);
|
||||||
|
switchToTextButtonInInputBar.setVisibility(View.VISIBLE);
|
||||||
|
mHelper.resetState();
|
||||||
|
});
|
||||||
|
Log.e(TAG, "switchToAudioLayout: post event");
|
||||||
|
EventBus.getDefault().post(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 隐藏键盘布局
|
||||||
|
public 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 showInputMethod(EditText editTextMessage) {
|
||||||
|
editTextMessage.requestFocus();
|
||||||
|
//如果已经显示,则继续操作时不需要把光标定位到最后
|
||||||
|
if (!isKeyboardShowed) {
|
||||||
|
editTextMessage.setSelection(editTextMessage.getText().length());
|
||||||
|
isKeyboardShowed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mHelper.toKeyboardState();
|
||||||
|
container.proxy.onInputPanelExpand();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restoreText(boolean clearText) {
|
||||||
|
if (clearText) {
|
||||||
|
messageEditText.setText("");
|
||||||
|
}
|
||||||
|
checkSendButtonEnable(messageEditText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示发送或更多
|
||||||
|
*
|
||||||
|
* @param editText
|
||||||
|
*/
|
||||||
|
private void checkSendButtonEnable(EditText editText) {
|
||||||
|
String textMessage = editText.getText().toString();
|
||||||
|
setEditTextState();
|
||||||
|
if (!TextUtils.isEmpty(StringUtil.removeBlanks(textMessage)) && editText.hasFocus()) {
|
||||||
|
sendMessageButtonInInputBar.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
sendMessageButtonInInputBar.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* *************** 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ****************************** 语音 ***********************************
|
||||||
|
*/
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
private void initAudioRecordButton() {
|
||||||
|
audioRecordBtn.setOnTouchListener((v, 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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化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.bg_message_voice);
|
||||||
|
stopAudioRecordAnim();
|
||||||
|
|
||||||
|
if (!cancel) {
|
||||||
|
EventBus.getDefault().post(new ActiveEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消语音录制
|
||||||
|
*
|
||||||
|
* @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.bg_message_voice_pressed);
|
||||||
|
|
||||||
|
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) {
|
||||||
|
SingleToastUtil.showToast(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 (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 reloadActions(List<BaseAction> actions) {
|
||||||
|
this.actions = actions;
|
||||||
|
for (int i = 0; i < this.actions.size(); ++i) {
|
||||||
|
this.actions.get(i).setIndex(i);
|
||||||
|
this.actions.get(i).setContainer(container);
|
||||||
|
}
|
||||||
|
ActionsPanel.init(view, actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLimitLevel(boolean isChat, String msg) {
|
||||||
|
this.isChat = isChat;
|
||||||
|
setEditTextState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setEditTextState() {
|
||||||
|
if (!isChat) {
|
||||||
|
messageEditText.setHint("暂未达到可发起私聊等级");
|
||||||
|
messageEditText.setFocusable(false);
|
||||||
|
messageEditText.setFocusableInTouchMode(false);
|
||||||
|
messageEditText.setEnabled(false);
|
||||||
|
sendMessageButtonInInputBar.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
messageEditText.setHint("请输入消息");
|
||||||
|
messageEditText.setFocusable(true);
|
||||||
|
messageEditText.setFocusableInTouchMode(true);
|
||||||
|
messageEditText.setEnabled(true);
|
||||||
|
sendMessageButtonInInputBar.setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -17,6 +17,8 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.mango.core.room.event.MessageSizeEvent;
|
||||||
|
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||||
import com.netease.nim.uikit.R;
|
import com.netease.nim.uikit.R;
|
||||||
import com.netease.nim.uikit.api.NimUIKit;
|
import com.netease.nim.uikit.api.NimUIKit;
|
||||||
import com.netease.nim.uikit.api.model.user.UserInfoObserver;
|
import com.netease.nim.uikit.api.model.user.UserInfoObserver;
|
||||||
@@ -65,8 +67,6 @@ import com.netease.nimlib.sdk.robot.model.RobotAttachment;
|
|||||||
import com.netease.nimlib.sdk.robot.model.RobotMsgType;
|
import com.netease.nimlib.sdk.robot.model.RobotMsgType;
|
||||||
import com.netease.nimlib.sdk.team.constant.TeamMemberType;
|
import com.netease.nimlib.sdk.team.constant.TeamMemberType;
|
||||||
import com.netease.nimlib.sdk.team.model.TeamMember;
|
import com.netease.nimlib.sdk.team.model.TeamMember;
|
||||||
import com.mango.core.room.event.MessageSizeEvent;
|
|
||||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ public class MessageListPanelEx {
|
|||||||
private static final int REQUEST_CODE_FORWARD_TEAM = 0x02;
|
private static final int REQUEST_CODE_FORWARD_TEAM = 0x02;
|
||||||
// 背景图片缓存
|
// 背景图片缓存
|
||||||
private static Pair<String, Bitmap> background;
|
private static Pair<String, Bitmap> background;
|
||||||
private static Comparator<IMMessage> comp = new Comparator<IMMessage>() {
|
private static final Comparator<IMMessage> comp = new Comparator<IMMessage>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(IMMessage o1, IMMessage o2) {
|
public int compare(IMMessage o1, IMMessage o2) {
|
||||||
@@ -97,7 +97,7 @@ public class MessageListPanelEx {
|
|||||||
};
|
};
|
||||||
// container
|
// container
|
||||||
private Container container;
|
private Container container;
|
||||||
private View rootView;
|
private final View rootView;
|
||||||
// message list view
|
// message list view
|
||||||
private RecyclerView messageListView;
|
private RecyclerView messageListView;
|
||||||
private List<IMMessage> items;
|
private List<IMMessage> items;
|
||||||
@@ -107,15 +107,15 @@ public class MessageListPanelEx {
|
|||||||
private IncomingMsgPrompt incomingMsgPrompt;
|
private IncomingMsgPrompt incomingMsgPrompt;
|
||||||
private Handler uiHandler;
|
private Handler uiHandler;
|
||||||
// 仅显示消息记录,不接收和发送消息
|
// 仅显示消息记录,不接收和发送消息
|
||||||
private boolean recordOnly;
|
private final boolean recordOnly;
|
||||||
// 从服务器拉取消息记录
|
// 从服务器拉取消息记录
|
||||||
private boolean remote;
|
private final boolean remote;
|
||||||
// 语音转文字
|
// 语音转文字
|
||||||
private VoiceTrans voiceTrans;
|
private VoiceTrans voiceTrans;
|
||||||
// 待转发消息
|
// 待转发消息
|
||||||
private IMMessage forwardMessage;
|
private IMMessage forwardMessage;
|
||||||
private CountDownTimer countDownTimer;
|
private CountDownTimer countDownTimer;
|
||||||
private OnItemClickListener listener = new OnItemClickListener() {
|
private final OnItemClickListener listener = new OnItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onItemClick(IRecyclerView adapter, View view, int position) {
|
public void onItemClick(IRecyclerView adapter, View view, int position) {
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ public class MessageListPanelEx {
|
|||||||
container.activity.startActivity(intent);
|
container.activity.startActivity(intent);
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (ActivityNotFoundException e) {
|
||||||
// Toast.makeText(container.activity, "路径错误", Toast.LENGTH_SHORT).show();
|
// Toast.makeText(container.activity, "路径错误", Toast.LENGTH_SHORT).show();
|
||||||
SingleToastUtil.showToastShort("路径错误");
|
SingleToastUtil.showToast("路径错误");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (LinkElement.TYPE_BLOCK.equals(element.getType())) {
|
} else if (LinkElement.TYPE_BLOCK.equals(element.getType())) {
|
||||||
@@ -162,7 +162,7 @@ public class MessageListPanelEx {
|
|||||||
/**
|
/**
|
||||||
* 消息状态变化观察者
|
* 消息状态变化观察者
|
||||||
*/
|
*/
|
||||||
private Observer<IMMessage> messageStatusObserver = new Observer<IMMessage>() {
|
private final Observer<IMMessage> messageStatusObserver = new Observer<IMMessage>() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(IMMessage message) {
|
public void onEvent(IMMessage message) {
|
||||||
if (isMyMessage(message)) {
|
if (isMyMessage(message)) {
|
||||||
@@ -173,7 +173,7 @@ public class MessageListPanelEx {
|
|||||||
/**
|
/**
|
||||||
* 消息附件上传/下载进度观察者
|
* 消息附件上传/下载进度观察者
|
||||||
*/
|
*/
|
||||||
private Observer<AttachmentProgress> attachmentProgressObserver = new Observer<AttachmentProgress>() {
|
private final Observer<AttachmentProgress> attachmentProgressObserver = new Observer<AttachmentProgress>() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(AttachmentProgress progress) {
|
public void onEvent(AttachmentProgress progress) {
|
||||||
onAttachmentProgressChange(progress);
|
onAttachmentProgressChange(progress);
|
||||||
@@ -182,7 +182,7 @@ public class MessageListPanelEx {
|
|||||||
/**
|
/**
|
||||||
* 本地消息接收观察者
|
* 本地消息接收观察者
|
||||||
*/
|
*/
|
||||||
private MessageListPanelHelper.LocalMessageObserver incomingLocalMessageObserver = new MessageListPanelHelper.LocalMessageObserver() {
|
private final MessageListPanelHelper.LocalMessageObserver incomingLocalMessageObserver = new MessageListPanelHelper.LocalMessageObserver() {
|
||||||
@Override
|
@Override
|
||||||
public void onAddMessage(IMMessage message) {
|
public void onAddMessage(IMMessage message) {
|
||||||
if (message == null || !container.account.equals(message.getSessionId())) {
|
if (message == null || !container.account.equals(message.getSessionId())) {
|
||||||
@@ -202,7 +202,7 @@ public class MessageListPanelEx {
|
|||||||
/**
|
/**
|
||||||
* 消息撤回观察者
|
* 消息撤回观察者
|
||||||
*/
|
*/
|
||||||
private Observer<RevokeMsgNotification> revokeMessageObserver = new Observer<RevokeMsgNotification>() {
|
private final Observer<RevokeMsgNotification> revokeMessageObserver = new Observer<RevokeMsgNotification>() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(RevokeMsgNotification notification) {
|
public void onEvent(RevokeMsgNotification notification) {
|
||||||
if (notification == null || notification.getMessage() == null) {
|
if (notification == null || notification.getMessage() == null) {
|
||||||
@@ -282,10 +282,10 @@ public class MessageListPanelEx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initListView(IMMessage anchor) {
|
private void initListView(IMMessage anchor) {
|
||||||
listviewBk = (ImageView) rootView.findViewById(R.id.message_activity_background);
|
listviewBk = rootView.findViewById(R.id.message_activity_background);
|
||||||
|
|
||||||
// RecyclerView
|
// RecyclerView
|
||||||
messageListView = (RecyclerView) rootView.findViewById(R.id.messageListView);
|
messageListView = rootView.findViewById(R.id.messageListView);
|
||||||
messageListView.setLayoutManager(new LinearLayoutManager(container.activity));
|
messageListView.setLayoutManager(new LinearLayoutManager(container.activity));
|
||||||
messageListView.requestDisallowInterceptTouchEvent(true);
|
messageListView.requestDisallowInterceptTouchEvent(true);
|
||||||
messageListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
messageListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
@@ -339,12 +339,7 @@ public class MessageListPanelEx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void scrollToBottom() {
|
public void scrollToBottom() {
|
||||||
uiHandler.postDelayed(new Runnable() {
|
doScrollToBottom();
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
doScrollToBottom();
|
|
||||||
}
|
|
||||||
}, 200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doScrollToBottom() {
|
private void doScrollToBottom() {
|
||||||
@@ -603,15 +598,11 @@ public class MessageListPanelEx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean receiveReceiptCheck(final IMMessage msg) {
|
private boolean receiveReceiptCheck(final IMMessage msg) {
|
||||||
if (msg != null && msg.getSessionType() == SessionTypeEnum.P2P
|
return msg != null && msg.getSessionType() == SessionTypeEnum.P2P
|
||||||
&& msg.getDirect() == MsgDirectionEnum.Out
|
&& msg.getDirect() == MsgDirectionEnum.Out
|
||||||
&& msg.getMsgType() != MsgTypeEnum.tip
|
&& msg.getMsgType() != MsgTypeEnum.tip
|
||||||
&& msg.getMsgType() != MsgTypeEnum.notification
|
&& msg.getMsgType() != MsgTypeEnum.notification
|
||||||
&& msg.isRemoteRead()) {
|
&& msg.isRemoteRead();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -649,12 +640,8 @@ public class MessageListPanelEx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean sendReceiptCheck(final IMMessage msg) {
|
private boolean sendReceiptCheck(final IMMessage msg) {
|
||||||
if (msg == null || msg.getDirect() != MsgDirectionEnum.In ||
|
return msg != null && msg.getDirect() == MsgDirectionEnum.In &&
|
||||||
msg.getMsgType() == MsgTypeEnum.tip || msg.getMsgType() == MsgTypeEnum.notification) {
|
msg.getMsgType() != MsgTypeEnum.tip && msg.getMsgType() != MsgTypeEnum.notification; // 非收到的消息,Tip消息和通知类消息,不要发已读回执
|
||||||
return false; // 非收到的消息,Tip消息和通知类消息,不要发已读回执
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除消息
|
// 删除消息
|
||||||
@@ -699,7 +686,7 @@ public class MessageListPanelEx {
|
|||||||
|
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
// Toast.makeText(container.activity, "该类型不支持转发", Toast.LENGTH_SHORT).show();
|
// Toast.makeText(container.activity, "该类型不支持转发", Toast.LENGTH_SHORT).show();
|
||||||
SingleToastUtil.showToastShort("该类型不支持转发");
|
SingleToastUtil.showToast("该类型不支持转发");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -742,15 +729,15 @@ public class MessageListPanelEx {
|
|||||||
|
|
||||||
private class MessageLoader implements BaseFetchLoadAdapter.RequestLoadMoreListener, BaseFetchLoadAdapter.RequestFetchMoreListener {
|
private class MessageLoader implements BaseFetchLoadAdapter.RequestLoadMoreListener, BaseFetchLoadAdapter.RequestFetchMoreListener {
|
||||||
|
|
||||||
private int loadMsgCount = NimUIKitImpl.getOptions().messageCountLoadOnce;
|
private final int loadMsgCount = NimUIKitImpl.getOptions().messageCountLoadOnce;
|
||||||
|
|
||||||
private QueryDirectionEnum direction = null;
|
private QueryDirectionEnum direction = null;
|
||||||
|
|
||||||
private IMMessage anchor;
|
private final IMMessage anchor;
|
||||||
private boolean remote;
|
private final boolean remote;
|
||||||
|
|
||||||
private boolean firstLoad = true;
|
private boolean firstLoad = true;
|
||||||
private RequestCallback<List<IMMessage>> callback = new RequestCallbackWrapper<List<IMMessage>>() {
|
private final RequestCallback<List<IMMessage>> callback = new RequestCallbackWrapper<List<IMMessage>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(int code, List<IMMessage> messages, Throwable exception) {
|
public void onResult(int code, List<IMMessage> messages, Throwable exception) {
|
||||||
if (code != ResponseCode.RES_SUCCESS || exception != null) {
|
if (code != ResponseCode.RES_SUCCESS || exception != null) {
|
||||||
@@ -1209,8 +1196,7 @@ public class MessageListPanelEx {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick() {
|
public void onClick() {
|
||||||
// Toast.makeText(container.activity, finalContent, Toast.LENGTH_SHORT).show();
|
SingleToastUtil.showToast(finalContent);
|
||||||
SingleToastUtil.showToastShort(finalContent);
|
|
||||||
setEarPhoneMode(!UserPreferences.isEarPhoneModeEnable(), true);
|
setEarPhoneMode(!UserPreferences.isEarPhoneModeEnable(), true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1257,8 +1243,7 @@ public class MessageListPanelEx {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick() {
|
public void onClick() {
|
||||||
if (!NetworkUtil.isNetAvailable(container.activity)) {
|
if (!NetworkUtil.isNetAvailable(container.activity)) {
|
||||||
// Toast.makeText(container.activity, R.string.network_is_not_available, Toast.LENGTH_SHORT).show();
|
SingleToastUtil.showToast(R.string.network_is_not_available);
|
||||||
SingleToastUtil.showToastShort(R.string.network_is_not_available);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NIMClient.getService(MsgService.class).revokeMessage(item).setCallback(new RequestCallback<Void>() {
|
NIMClient.getService(MsgService.class).revokeMessage(item).setCallback(new RequestCallback<Void>() {
|
||||||
@@ -1271,11 +1256,9 @@ public class MessageListPanelEx {
|
|||||||
@Override
|
@Override
|
||||||
public void onFailed(int code) {
|
public void onFailed(int code) {
|
||||||
if (code == ResponseCode.RES_OVERDUE) {
|
if (code == ResponseCode.RES_OVERDUE) {
|
||||||
// Toast.makeText(container.activity, R.string.revoke_failed, Toast.LENGTH_SHORT).show();
|
SingleToastUtil.showToast(R.string.revoke_failed);
|
||||||
SingleToastUtil.showToastShort(R.string.revoke_failed);
|
|
||||||
} else {
|
} else {
|
||||||
// Toast.makeText(container.activity, "revoke msg failed, code:" + code, Toast.LENGTH_SHORT).show();
|
SingleToastUtil.showToast("revoke msg failed, code:" + code);
|
||||||
SingleToastUtil.showToastShort("revoke msg failed, code:" + code);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,6 +17,31 @@ import androidx.annotation.Nullable;
|
|||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.mango.core.audio.event.VoiceShakeHeartEvent;
|
||||||
|
import com.mango.core.auth.AuthModel;
|
||||||
|
import com.mango.core.im.friend.IMFriendModel;
|
||||||
|
import com.mango.core.mentoring_relationship.event.MentoringSuccessEvent;
|
||||||
|
import com.mango.core.noble.NobleUtil;
|
||||||
|
import com.mango.core.praise.PraiseModel;
|
||||||
|
import com.mango.core.praise.event.IsLikedEvent;
|
||||||
|
import com.mango.core.praise.event.PraiseEvent;
|
||||||
|
import com.mango.core.user.UserModel;
|
||||||
|
import com.mango.core.user.bean.UserDetailInfo;
|
||||||
|
import com.mango.core.user.bean.UserInfo;
|
||||||
|
import com.mango.core.utils.StringExtensionKt;
|
||||||
|
import com.mango.core.utils.SystemUidUtil;
|
||||||
|
import com.mango.core.utils.net.BeanObserver;
|
||||||
|
import com.mango.moshen.R;
|
||||||
|
import com.mango.moshen.avroom.activity.AVRoomActivity;
|
||||||
|
import com.mango.moshen.common.widget.CustomImageSpan;
|
||||||
|
import com.mango.moshen.mentoring_relationship.dialog.BuildMentoringRelationshipSuccessDialog;
|
||||||
|
import com.mango.moshen.ui.im.audio.ShakeHeartDialogFragment;
|
||||||
|
import com.mango.moshen.ui.im.fragment.MessageFragment;
|
||||||
|
import com.mango.moshen.ui.user.UserInfoActivity;
|
||||||
|
import com.mango.moshen.ui.utils.ImageLoadUtils;
|
||||||
|
import com.mango.xchat_android_library.utils.ListUtils;
|
||||||
|
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||||
|
import com.netease.nim.uikit.StatusBarUtil;
|
||||||
import com.netease.nim.uikit.api.NimUIKit;
|
import com.netease.nim.uikit.api.NimUIKit;
|
||||||
import com.netease.nim.uikit.api.model.contact.ContactChangedObserver;
|
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.main.OnlineStateChangeObserver;
|
||||||
@@ -31,33 +56,6 @@ import com.netease.nimlib.sdk.Observer;
|
|||||||
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
|
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
|
||||||
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||||
import com.netease.nimlib.sdk.msg.model.CustomNotification;
|
import com.netease.nimlib.sdk.msg.model.CustomNotification;
|
||||||
import com.mango.moshen.R;
|
|
||||||
import com.mango.moshen.avroom.activity.AVRoomActivity;
|
|
||||||
import com.mango.moshen.common.widget.CustomImageSpan;
|
|
||||||
import com.mango.moshen.ui.im.audio.ShakeHeartDialogFragment;
|
|
||||||
import com.mango.moshen.ui.im.fragment.MessageFragment;
|
|
||||||
import com.mango.moshen.ui.user.UserInfoActivity;
|
|
||||||
import com.mango.moshen.ui.utils.ImageLoadUtils;
|
|
||||||
import com.mango.moshen.mentoring_relationship.dialog.BuildMentoringRelationshipSuccessDialog;
|
|
||||||
import com.mango.core.audio.event.VoiceShakeHeartEvent;
|
|
||||||
import com.mango.core.auth.AuthModel;
|
|
||||||
import com.mango.core.im.friend.IMFriendModel;
|
|
||||||
import com.mango.core.initial.InitialModel;
|
|
||||||
import com.mango.core.initial.bean.InitInfo;
|
|
||||||
import com.mango.core.level.UserLevelVo;
|
|
||||||
import com.mango.core.mentoring_relationship.event.MentoringSuccessEvent;
|
|
||||||
import com.mango.core.noble.NobleUtil;
|
|
||||||
import com.mango.core.praise.PraiseModel;
|
|
||||||
import com.mango.core.praise.event.IsLikedEvent;
|
|
||||||
import com.mango.core.praise.event.PraiseEvent;
|
|
||||||
import com.mango.core.user.UserModel;
|
|
||||||
import com.mango.core.user.bean.UserDetailInfo;
|
|
||||||
import com.mango.core.user.bean.UserInfo;
|
|
||||||
import com.mango.core.utils.StringExtensionKt;
|
|
||||||
import com.mango.core.utils.SystemUidUtil;
|
|
||||||
import com.mango.core.utils.net.BeanObserver;
|
|
||||||
import com.mango.xchat_android_library.utils.ListUtils;
|
|
||||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
@@ -414,21 +412,6 @@ public class NimP2PMessageActivity extends NewBaseMessageActivity {
|
|||||||
MessageFragment fragment = new MessageFragment();
|
MessageFragment fragment = new MessageFragment();
|
||||||
fragment.setArguments(arguments);
|
fragment.setArguments(arguments);
|
||||||
fragment.setContainerId(R.id.message_fragment_container);
|
fragment.setContainerId(R.id.message_fragment_container);
|
||||||
|
|
||||||
// 等级限制:官方小秘书 和 系统消息,不设置等级限制
|
|
||||||
if (!SystemUidUtil.isSystemUid(sessionId)) {
|
|
||||||
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
|
|
||||||
if (userInfo != null) {
|
|
||||||
UserLevelVo userLevelVo = userInfo.getUserLevelVo();
|
|
||||||
if (userLevelVo != null) {
|
|
||||||
fragment.setCurrentLevel(userLevelVo.experLevelSeq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InitInfo initInfo = InitialModel.get().getCacheInitInfo();
|
|
||||||
if (initInfo != null) {
|
|
||||||
fragment.setLimitLevel(initInfo.getPrivateChatLevelNo());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,4 +469,16 @@ public class NimP2PMessageActivity extends NewBaseMessageActivity {
|
|||||||
ShakeHeartDialogFragment shakeHeartDialogFragment = ShakeHeartDialogFragment.newInstance(event.showTextHint);
|
ShakeHeartDialogFragment shakeHeartDialogFragment = ShakeHeartDialogFragment.newInstance(event.showTextHint);
|
||||||
shakeHeartDialogFragment.show(getSupportFragmentManager(), "shake_heart");
|
shakeHeartDialogFragment.show(getSupportFragmentManager(), "shake_heart");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean needSteepStateBar() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setStatusBar() {
|
||||||
|
super.setStatusBar();
|
||||||
|
StatusBarUtil.transparencyBar(this);
|
||||||
|
StatusBarUtil.StatusBarLightMode(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,24 @@ import android.widget.TextView;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import com.mango.core.UriProvider;
|
||||||
|
import com.mango.core.auth.AuthModel;
|
||||||
|
import com.mango.core.im.chatterbox.ChatterBoxHelper;
|
||||||
|
import com.mango.core.im.chatterbox.HideInputEvent;
|
||||||
|
import com.mango.core.room.event.MessageSizeEvent;
|
||||||
|
import com.mango.core.statistic.StatisticManager;
|
||||||
|
import com.mango.core.statistic.protocol.StatisticsProtocol;
|
||||||
|
import com.mango.moshen.R;
|
||||||
|
import com.mango.moshen.common.widget.OriginalDrawStatusClickSpan;
|
||||||
|
import com.mango.moshen.ui.im.GreetPresenter;
|
||||||
|
import com.mango.moshen.ui.im.InputPanel;
|
||||||
|
import com.mango.moshen.ui.im.MessageListPanelEx;
|
||||||
|
import com.mango.moshen.ui.im.chat.MVHChatterBoxStart;
|
||||||
|
import com.mango.moshen.ui.im.model.IMCustomModel;
|
||||||
|
import com.mango.moshen.ui.webview.CommonWebViewActivity;
|
||||||
|
import com.mango.moshen.utils.PushMessageHandler;
|
||||||
|
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||||
|
import com.mango.xchat_android_library.utils.config.BasicConfig;
|
||||||
import com.netease.nim.uikit.api.UIKitOptions;
|
import com.netease.nim.uikit.api.UIKitOptions;
|
||||||
import com.netease.nim.uikit.api.model.main.CustomPushContentProvider;
|
import com.netease.nim.uikit.api.model.main.CustomPushContentProvider;
|
||||||
import com.netease.nim.uikit.api.model.session.SessionCustomization;
|
import com.netease.nim.uikit.api.model.session.SessionCustomization;
|
||||||
@@ -28,7 +46,6 @@ 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.constant.Extras;
|
||||||
import com.netease.nim.uikit.business.session.module.Container;
|
import com.netease.nim.uikit.business.session.module.Container;
|
||||||
import com.netease.nim.uikit.business.session.module.ModuleProxy;
|
import com.netease.nim.uikit.business.session.module.ModuleProxy;
|
||||||
import com.netease.nim.uikit.business.session.module.input.InputPanel;
|
|
||||||
import com.netease.nim.uikit.business.session.module.input.NimAudioChatEvent;
|
import com.netease.nim.uikit.business.session.module.input.NimAudioChatEvent;
|
||||||
import com.netease.nim.uikit.business.session.module.input.NimImageActionEvent;
|
import com.netease.nim.uikit.business.session.module.input.NimImageActionEvent;
|
||||||
import com.netease.nim.uikit.common.fragment.TFragment;
|
import com.netease.nim.uikit.common.fragment.TFragment;
|
||||||
@@ -51,25 +68,6 @@ import com.netease.nimlib.sdk.robot.model.NimRobotInfo;
|
|||||||
import com.netease.nimlib.sdk.robot.model.RobotAttachment;
|
import com.netease.nimlib.sdk.robot.model.RobotAttachment;
|
||||||
import com.netease.nimlib.sdk.robot.model.RobotMsgType;
|
import com.netease.nimlib.sdk.robot.model.RobotMsgType;
|
||||||
import com.tbruyelle.rxpermissions2.RxPermissions;
|
import com.tbruyelle.rxpermissions2.RxPermissions;
|
||||||
import com.mango.moshen.R;
|
|
||||||
import com.mango.moshen.common.widget.OriginalDrawStatusClickSpan;
|
|
||||||
import com.mango.moshen.ui.im.GreetPresenter;
|
|
||||||
import com.mango.moshen.ui.im.MessageListPanelEx;
|
|
||||||
import com.mango.moshen.ui.im.chat.MVHChatterBoxStart;
|
|
||||||
import com.mango.moshen.ui.im.model.IMCustomModel;
|
|
||||||
import com.mango.moshen.ui.webview.CommonWebViewActivity;
|
|
||||||
import com.mango.moshen.utils.PushMessageHandler;
|
|
||||||
import com.mango.core.UriProvider;
|
|
||||||
import com.mango.core.auth.AuthModel;
|
|
||||||
import com.mango.core.im.chatterbox.ChatterBoxHelper;
|
|
||||||
import com.mango.core.im.chatterbox.HideInputEvent;
|
|
||||||
import com.mango.core.im.custom.bean.CustomAttachment;
|
|
||||||
import com.mango.core.im.custom.bean.ImTipAttachment;
|
|
||||||
import com.mango.core.room.event.MessageSizeEvent;
|
|
||||||
import com.mango.core.statistic.StatisticManager;
|
|
||||||
import com.mango.core.statistic.protocol.StatisticsProtocol;
|
|
||||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
|
||||||
import com.mango.xchat_android_library.utils.config.BasicConfig;
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
@@ -103,6 +101,7 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
|||||||
protected InputPanel inputPanel;
|
protected InputPanel inputPanel;
|
||||||
protected MessageListPanelEx messageListPanel;
|
protected MessageListPanelEx messageListPanel;
|
||||||
protected AitManager aitManager;
|
protected AitManager aitManager;
|
||||||
|
private boolean inRoom;
|
||||||
/**
|
/**
|
||||||
* 消息接收观察者
|
* 消息接收观察者
|
||||||
*/
|
*/
|
||||||
@@ -190,27 +189,12 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送提示信息
|
|
||||||
*
|
|
||||||
* @param msg
|
|
||||||
*/
|
|
||||||
public void sendTipMessage(String msg, int second) {
|
|
||||||
ImTipAttachment attachment = new ImTipAttachment(CustomAttachment.CUSTOM_MSG_IM_TIP, second);
|
|
||||||
attachment.setMsg(msg);
|
|
||||||
IMMessage message = MessageBuilder.createCustomMessage(sessionId, SessionTypeEnum.P2P, attachment);
|
|
||||||
sendMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean onBackPressed() {
|
public boolean onBackPressed() {
|
||||||
if (inputPanel.collapse(true)) {
|
if (inputPanel.collapse(true)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messageListPanel.onBackPressed()) {
|
return messageListPanel.onBackPressed();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshMessageList() {
|
public void refreshMessageList() {
|
||||||
@@ -243,8 +227,6 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
|||||||
|
|
||||||
initAitManager();
|
initAitManager();
|
||||||
|
|
||||||
inputPanel.switchRobotMode(NimUIKitImpl.getRobotInfoProvider().getRobotByAccount(sessionId) != null);
|
|
||||||
|
|
||||||
registerObservers(true);
|
registerObservers(true);
|
||||||
|
|
||||||
if (customization != null) {
|
if (customization != null) {
|
||||||
@@ -302,7 +284,7 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
|||||||
*/
|
*/
|
||||||
// 是否允许发送消息
|
// 是否允许发送消息
|
||||||
protected boolean isAllowSendMessage(final IMMessage message) {
|
protected boolean isAllowSendMessage(final IMMessage message) {
|
||||||
return true;
|
return isChat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -324,7 +306,9 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean sendMessage(IMMessage message) {
|
public boolean sendMessage(IMMessage message) {
|
||||||
|
|
||||||
if (!isAllowSendMessage(message)) {
|
if (!isAllowSendMessage(message)) {
|
||||||
|
SingleToastUtil.showToast("未到达私聊等级!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,8 +330,6 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
|||||||
|
|
||||||
final IMMessage msg = message;
|
final IMMessage msg = message;
|
||||||
appendPushConfig(message);
|
appendPushConfig(message);
|
||||||
// send message to server and save to db
|
|
||||||
IMMessage finalMessage = message;
|
|
||||||
NIMClient.getService(MsgService.class).sendMessage(message, false).setCallback(new RequestCallback<Void>() {
|
NIMClient.getService(MsgService.class).sendMessage(message, false).setCallback(new RequestCallback<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Void param) {
|
public void onSuccess(Void param) {
|
||||||
@@ -542,10 +524,6 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
|||||||
// 操作面板集合
|
// 操作面板集合
|
||||||
protected List<BaseAction> getActionList() {
|
protected List<BaseAction> getActionList() {
|
||||||
List<BaseAction> actions = new ArrayList<>();
|
List<BaseAction> actions = new ArrayList<>();
|
||||||
// actions.add(new ImageAction());
|
|
||||||
// actions.add(new VideoAction());
|
|
||||||
// actions.add(new LocationAction());
|
|
||||||
|
|
||||||
if (customization != null && customization.actions != null) {
|
if (customization != null && customization.actions != null) {
|
||||||
actions.addAll(customization.actions);
|
actions.addAll(customization.actions);
|
||||||
}
|
}
|
||||||
@@ -566,18 +544,6 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
|||||||
messageListPanel.receiveReceipt();
|
messageListPanel.receiveReceipt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 重新加载 输入面板
|
|
||||||
*
|
|
||||||
* @param sessionCustomization
|
|
||||||
*/
|
|
||||||
public void reloadInputPanel(SessionCustomization sessionCustomization) {
|
|
||||||
this.customization = sessionCustomization;
|
|
||||||
Container container = new Container(getActivity(), sessionId, sessionType, this);
|
|
||||||
inputPanel.reload(container, customization);
|
|
||||||
inputPanel.reloadActions(sessionCustomization.actions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
public void onHideInput(HideInputEvent event) {
|
public void onHideInput(HideInputEvent event) {
|
||||||
if (inputPanel != null) {
|
if (inputPanel != null) {
|
||||||
@@ -592,51 +558,54 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
|||||||
if (inputPanel != null) {
|
if (inputPanel != null) {
|
||||||
if (event.getSize() > 0) {
|
if (event.getSize() > 0) {
|
||||||
tvChatLimit.setVisibility(View.GONE);
|
tvChatLimit.setVisibility(View.GONE);
|
||||||
|
isChat = true;
|
||||||
inputPanel.setLimitLevel(true, "");
|
inputPanel.setLimitLevel(true, "");
|
||||||
} else {
|
} else {
|
||||||
IMCustomModel.get().getPrivateChatLimit(sessionId).subscribe(((privateChatLimitInfo, throwable) -> {
|
IMCustomModel.get()
|
||||||
if (throwable != null) {
|
.getPrivateChatLimit(sessionId)
|
||||||
throwable.printStackTrace();
|
.subscribe(((privateChatLimitInfo, throwable) -> {
|
||||||
} else {
|
if (throwable != null) {
|
||||||
isChat = privateChatLimitInfo.isChat();
|
throwable.printStackTrace();
|
||||||
hintText = "暂未达到可发起私聊等级";
|
} else {
|
||||||
inputPanel.setLimitLevel(privateChatLimitInfo.isChat(), privateChatLimitInfo.getMessage());
|
isChat = privateChatLimitInfo.isChat();
|
||||||
|
hintText = "暂未达到可发起私聊等级";
|
||||||
|
inputPanel.setLimitLevel(privateChatLimitInfo.isChat(), privateChatLimitInfo.getMessage());
|
||||||
|
|
||||||
String experLevel = "财富等级≥" + privateChatLimitInfo.getWealthLevel();
|
String experLevel = "财富等级≥" + privateChatLimitInfo.getWealthLevel();
|
||||||
String charmLevel = "魅力等级≥" + privateChatLimitInfo.getCharmLevel();
|
String charmLevel = "魅力等级≥" + privateChatLimitInfo.getCharmLevel();
|
||||||
String privacyAgreementDescTip = getContext().getString(R.string.text_chat_limit, experLevel, charmLevel);
|
String privacyAgreementDescTip = getContext().getString(R.string.text_chat_limit, experLevel, charmLevel);
|
||||||
SpannableString ss = new SpannableString(privacyAgreementDescTip);
|
SpannableString ss = new SpannableString(privacyAgreementDescTip);
|
||||||
int experLevelIndex = privacyAgreementDescTip.indexOf(experLevel);
|
int experLevelIndex = privacyAgreementDescTip.indexOf(experLevel);
|
||||||
int charmLevelIndex = privacyAgreementDescTip.indexOf(charmLevel);
|
int charmLevelIndex = privacyAgreementDescTip.indexOf(charmLevel);
|
||||||
|
|
||||||
|
|
||||||
ss.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.appColor)), experLevelIndex, experLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
ss.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.appColor)), experLevelIndex, experLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||||
ss.setSpan(new OriginalDrawStatusClickSpan(ContextCompat.getColor(getContext(), R.color.appColor)) {
|
ss.setSpan(new OriginalDrawStatusClickSpan(ContextCompat.getColor(getContext(), R.color.appColor)) {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(@NonNull View widget) {
|
public void onClick(@NonNull View widget) {
|
||||||
if (widget instanceof TextView)
|
if (widget instanceof TextView)
|
||||||
((TextView) widget).setHighlightColor(getResources().getColor(android.R.color.transparent));
|
((TextView) widget).setHighlightColor(getResources().getColor(android.R.color.transparent));
|
||||||
|
|
||||||
CommonWebViewActivity.start(getContext(), UriProvider.getUserLevelUrl());
|
CommonWebViewActivity.start(getContext(), UriProvider.getUserLevelUrl());
|
||||||
|
}
|
||||||
|
}, experLevelIndex, experLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||||
|
ss.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.appColor)), charmLevelIndex, charmLevelIndex + charmLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||||
|
ss.setSpan(new OriginalDrawStatusClickSpan(ContextCompat.getColor(getContext(), R.color.appColor)) {
|
||||||
|
@Override
|
||||||
|
public void onClick(@NonNull View widget) {
|
||||||
|
if (widget instanceof TextView)
|
||||||
|
((TextView) widget).setHighlightColor(getResources().getColor(android.R.color.transparent));
|
||||||
|
|
||||||
|
CommonWebViewActivity.start(getContext(), UriProvider.getUserLevelUrl());
|
||||||
|
}
|
||||||
|
}, charmLevelIndex, charmLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||||
|
|
||||||
|
tvChatLimit.setText(ss);
|
||||||
|
tvChatLimit.setHighlightColor(Color.TRANSPARENT);
|
||||||
|
tvChatLimit.setMovementMethod(new LinkMovementMethod());
|
||||||
|
tvChatLimit.setVisibility(isChat ? View.GONE : View.VISIBLE);
|
||||||
}
|
}
|
||||||
}, experLevelIndex, experLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
}));
|
||||||
ss.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.appColor)), charmLevelIndex, charmLevelIndex + charmLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
|
||||||
ss.setSpan(new OriginalDrawStatusClickSpan(ContextCompat.getColor(getContext(), R.color.appColor)) {
|
|
||||||
@Override
|
|
||||||
public void onClick(@NonNull View widget) {
|
|
||||||
if (widget instanceof TextView)
|
|
||||||
((TextView) widget).setHighlightColor(getResources().getColor(android.R.color.transparent));
|
|
||||||
|
|
||||||
CommonWebViewActivity.start(getContext(), UriProvider.getUserLevelUrl());
|
|
||||||
}
|
|
||||||
}, charmLevelIndex, charmLevelIndex + experLevel.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
|
||||||
|
|
||||||
tvChatLimit.setText(ss);
|
|
||||||
tvChatLimit.setHighlightColor(Color.TRANSPARENT);
|
|
||||||
tvChatLimit.setMovementMethod(new LinkMovementMethod());
|
|
||||||
tvChatLimit.setVisibility(isChat ? View.GONE : View.VISIBLE);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -672,12 +641,4 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLimitLevel(int limitLevel) {
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
public void setCurrentLevel(int currentLevel) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,8 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/bg_normal_1c1b22">
|
android:background="@color/bg_normal_1c1b22"
|
||||||
|
android:paddingTop="30dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<com.netease.nim.uikit.business.session.emoji.EmoticonPickerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/emoticon_picker_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_gravity="center">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/nim_message_item_text_body"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:autoLink="phone|email|web"
|
||||||
|
android:gravity="center_vertical|left"
|
||||||
|
android:includeFontPadding="false"
|
||||||
|
android:lineSpacingExtra="3dip"
|
||||||
|
android:maxWidth="222dp"
|
||||||
|
android:text="这是选择图片的玩意"
|
||||||
|
android:textColor="@color/text_title_white"
|
||||||
|
android:textSize="@dimen/dp_13" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@@ -1,58 +1,24 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<com.effective.android.panel.view.PanelSwitchLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/messageActivityLayout"
|
android:id="@+id/messageActivityLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/bg_normal_1c1b22"
|
android:background="@color/bg_normal_1c1b22"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
app:animationSpeed="standard">
|
||||||
|
|
||||||
<RelativeLayout
|
<com.effective.android.panel.view.content.LinearContentContainer
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dip"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1">
|
android:orientation="vertical"
|
||||||
|
app:edit_view="@id/editTextMessage">
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/fl_game"
|
|
||||||
android:layout_width="299dp"
|
|
||||||
android:layout_height="163dp"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_marginBottom="-10dp"
|
|
||||||
android:background="@drawable/chat_popup_game_bg"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:layout_marginTop="25dp"
|
|
||||||
android:text="Ta爱玩的游戏"
|
|
||||||
android:textColor="#ff666666"
|
|
||||||
android:textSize="18sp" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/iv_close"
|
|
||||||
android:layout_width="50dp"
|
|
||||||
android:layout_height="50dp"
|
|
||||||
android:layout_gravity="right"
|
|
||||||
android:layout_marginRight="10dp"
|
|
||||||
android:scaleType="center"
|
|
||||||
android:src="@drawable/chat_popup_game_close" />
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/recycler_view"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:layout_marginTop="55dp" />
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:id="@+id/message_activity_list_view_container"
|
android:id="@+id/message_activity_list_view_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="0dp"
|
||||||
android:layout_below="@id/fl_game"
|
|
||||||
android:layout_weight="1">
|
android:layout_weight="1">
|
||||||
|
|
||||||
<com.netease.nim.uikit.business.session.helper.MsgBkImageView
|
<com.netease.nim.uikit.business.session.helper.MsgBkImageView
|
||||||
@@ -72,7 +38,7 @@
|
|||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<com.mango.moshen.ui.im.AutoHidePanelRecyclerView
|
||||||
android:id="@+id/messageListView"
|
android:id="@+id/messageListView"
|
||||||
style="@style/recycler_view"
|
style="@style/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -120,18 +86,173 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_marginTop="@dimen/dp_10"
|
android:layout_marginTop="@dimen/dp_10"
|
||||||
android:text="哈哈哈哈哈"
|
|
||||||
android:paddingStart="@dimen/dp_10"
|
|
||||||
android:paddingEnd="@dimen/dp_10"
|
|
||||||
android:paddingTop="@dimen/dp_2"
|
|
||||||
android:paddingBottom="@dimen/dp_2"
|
|
||||||
android:background="@drawable/bg_chat_limit"
|
android:background="@drawable/bg_chat_limit"
|
||||||
android:visibility="gone"
|
android:paddingStart="@dimen/dp_10"
|
||||||
/>
|
android:paddingTop="@dimen/dp_2"
|
||||||
|
android:paddingEnd="@dimen/dp_10"
|
||||||
|
android:paddingBottom="@dimen/dp_2"
|
||||||
|
android:text="哈哈哈哈哈"
|
||||||
|
android:visibility="gone" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
<LinearLayout
|
||||||
|
android:id="@+id/textMessageLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="@dimen/bottom_component_margin_vertical"
|
||||||
|
android:paddingBottom="@dimen/bottom_component_margin_vertical">
|
||||||
|
|
||||||
<include layout="@layout/nim_message_activity_bottom_layout" />
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
</LinearLayout>
|
<FrameLayout
|
||||||
|
android:id="@+id/switchLayout"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/bottom_component_margin_horizontal"
|
||||||
|
android:layout_marginRight="@dimen/bottom_component_margin_horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/buttonAudioMessage"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:background="@drawable/nim_message_button_bottom_audio_selector"
|
||||||
|
android:contentDescription="@string/empty"
|
||||||
|
android:scaleType="center" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/buttonTextMessage"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:background="@drawable/nim_message_button_bottom_text_selector"
|
||||||
|
android:contentDescription="@string/empty"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/audioRecord"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginEnd="@dimen/bottom_component_margin_horizontal"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/bg_message_voice"
|
||||||
|
android:text="@string/record_audio"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/editTextMessage"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_marginEnd="@dimen/bottom_component_margin_horizontal"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:autoLink="web|email|phone"
|
||||||
|
android:background="@drawable/bg_message_input"
|
||||||
|
android:hint="@string/message_hint"
|
||||||
|
android:imeOptions="actionSend"
|
||||||
|
android:inputType="text"
|
||||||
|
android:maxLength="120"
|
||||||
|
android:maxLines="4"
|
||||||
|
android:paddingStart="@dimen/dp_10"
|
||||||
|
android:paddingEnd="10dp"
|
||||||
|
android:textColor="@color/color_C6C6E9"
|
||||||
|
android:textColorHint="@color/text_hint_555574"
|
||||||
|
android:textCursorDrawable="@null"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/emoji_button"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_marginEnd="@dimen/bottom_component_margin_horizontal"
|
||||||
|
android:background="@drawable/nim_message_button_bottom_emoji_selector"
|
||||||
|
android:contentDescription="@string/empty"
|
||||||
|
android:scaleType="center" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/buttonSendMessage"
|
||||||
|
android:layout_width="56dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
|
android:background="@drawable/common_btn_bg"
|
||||||
|
android:contentDescription="@string/empty"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/send"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="@dimen/sp_12"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_image"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:src="@drawable/message_input_ic_image" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_camera"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:layout_marginStart="88dp"
|
||||||
|
android:src="@drawable/message_input_ic_camera" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_gift"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
android:layout_marginStart="88dp"
|
||||||
|
android:src="@drawable/message_input_ic_gift" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.effective.android.panel.view.content.LinearContentContainer>
|
||||||
|
|
||||||
|
<!-- 面板区域,仅能包含PanelView-->
|
||||||
|
<com.effective.android.panel.view.panel.PanelContainer
|
||||||
|
android:id="@+id/panel_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<!-- 每一项面板 -->
|
||||||
|
<!-- panel_layout 用于指定面板该 ID 对应的布局 ,必须项-->
|
||||||
|
<!-- panel_trigger 用于用户点击该 ID 对应的 View 时切换到该面板 -->
|
||||||
|
<!-- panel_toggle 用于当该面板显示时 ,用户再次点击 panel_trigger 对应的 View 时是否回切输入法-->
|
||||||
|
<com.effective.android.panel.view.panel.PanelView
|
||||||
|
android:id="@+id/panel_emotion"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:panel_layout="@layout/nim_message_emoji_layout"
|
||||||
|
app:panel_trigger="@id/emoji_button" />
|
||||||
|
|
||||||
|
<com.effective.android.panel.view.panel.PanelView
|
||||||
|
android:id="@+id/panel_photo"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:panel_layout="@layout/nim_message_photo_layout"
|
||||||
|
app:panel_trigger="@id/iv_image" />
|
||||||
|
|
||||||
|
</com.effective.android.panel.view.panel.PanelContainer>
|
||||||
|
|
||||||
|
</com.effective.android.panel.view.PanelSwitchLayout>
|
@@ -13,6 +13,15 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.mango.core.im.friend.IMFriendModel;
|
||||||
|
import com.mango.core.manager.IMNetEaseManager;
|
||||||
|
import com.mango.core.manager.RoomEvent;
|
||||||
|
import com.mango.core.utils.SystemUidUtil;
|
||||||
|
import com.mango.moshen.R;
|
||||||
|
import com.mango.moshen.room_chat.event.ClickRootViewEvent;
|
||||||
|
import com.mango.moshen.ui.im.avtivity.NewBaseMessageActivity;
|
||||||
|
import com.mango.moshen.ui.im.fragment.MessageFragment;
|
||||||
|
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
||||||
import com.netease.nim.uikit.api.NimUIKit;
|
import com.netease.nim.uikit.api.NimUIKit;
|
||||||
import com.netease.nim.uikit.api.model.contact.ContactChangedObserver;
|
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.main.OnlineStateChangeObserver;
|
||||||
@@ -25,20 +34,6 @@ import com.netease.nimlib.sdk.Observer;
|
|||||||
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
|
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
|
||||||
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||||
import com.netease.nimlib.sdk.msg.model.CustomNotification;
|
import com.netease.nimlib.sdk.msg.model.CustomNotification;
|
||||||
import com.mango.moshen.R;
|
|
||||||
import com.mango.moshen.ui.im.avtivity.NewBaseMessageActivity;
|
|
||||||
import com.mango.moshen.ui.im.fragment.MessageFragment;
|
|
||||||
import com.mango.moshen.room_chat.event.ClickRootViewEvent;
|
|
||||||
import com.mango.core.im.friend.IMFriendModel;
|
|
||||||
import com.mango.core.initial.InitialModel;
|
|
||||||
import com.mango.core.initial.bean.InitInfo;
|
|
||||||
import com.mango.core.level.UserLevelVo;
|
|
||||||
import com.mango.core.manager.IMNetEaseManager;
|
|
||||||
import com.mango.core.manager.RoomEvent;
|
|
||||||
import com.mango.core.user.UserModel;
|
|
||||||
import com.mango.core.user.bean.UserInfo;
|
|
||||||
import com.mango.core.utils.SystemUidUtil;
|
|
||||||
import com.mango.xchat_android_library.utils.SingleToastUtil;
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
@@ -259,14 +254,11 @@ public class NimRoomP2PMessageActivity extends NewBaseMessageActivity {
|
|||||||
int id = json.getIntValue("id");
|
int id = json.getIntValue("id");
|
||||||
if (id == 1) {
|
if (id == 1) {
|
||||||
// 正在输入
|
// 正在输入
|
||||||
// Toast.makeText(NimRoomP2PMessageActivity.this, "对方正在输入...", Toast.LENGTH_LONG).show();
|
SingleToastUtil.showToast("对方正在输入...");
|
||||||
SingleToastUtil.showToastShort("对方正在输入...");
|
|
||||||
} else {
|
|
||||||
// Toast.makeText(NimP2PMessageActivity.this, "command: " + content, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,29 +273,12 @@ public class NimRoomP2PMessageActivity extends NewBaseMessageActivity {
|
|||||||
MessageFragment fragment = new MessageFragment();
|
MessageFragment fragment = new MessageFragment();
|
||||||
fragment.setArguments(arguments);
|
fragment.setArguments(arguments);
|
||||||
fragment.setContainerId(R.id.message_fragment_container);
|
fragment.setContainerId(R.id.message_fragment_container);
|
||||||
|
|
||||||
// 等级限制:官方小秘书 和 系统消息,不设置等级限制
|
|
||||||
if (!SystemUidUtil.isSystemUid(sessionId)) {
|
|
||||||
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
|
|
||||||
if (userInfo != null) {
|
|
||||||
UserLevelVo userLevelVo = userInfo.getUserLevelVo();
|
|
||||||
if (userLevelVo != null) {
|
|
||||||
fragment.setCurrentLevel(userLevelVo.experLevelSeq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InitInfo initInfo = InitialModel.get().getCacheInitInfo();
|
|
||||||
if (initInfo != null) {
|
|
||||||
fragment.setLimitLevel(initInfo.getPrivateChatLevelNo());
|
|
||||||
fragment.setLimitLevel(initInfo.getPrivateChatRegisterDay());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initToolBar() {
|
protected void initToolBar() {
|
||||||
//ToolBarOptions options = new NimToolBarOptions();
|
|
||||||
// setToolBar(R.id.toolbar, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -95,6 +95,9 @@ dependencies {
|
|||||||
|
|
||||||
api 'com.github.getActivity:ToastUtils:10.3'
|
api 'com.github.getActivity:ToastUtils:10.3'
|
||||||
|
|
||||||
|
api 'com.github.DSAppTeam:PanelSwitchHelper:v1.5.2'
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@@ -69,8 +69,6 @@ dependencies {
|
|||||||
annotationProcessor "com.github.bumptech.glide:compiler:${glideVersion}"
|
annotationProcessor "com.github.bumptech.glide:compiler:${glideVersion}"
|
||||||
|
|
||||||
implementation project(':library')
|
implementation project(':library')
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<solid android:color="#F4F4FA" />
|
<solid android:color="#F2F2F7" />
|
||||||
<corners android:radius="15dp" />
|
<corners android:radius="25dp" />
|
||||||
</shape>
|
</shape>
|
@@ -6,13 +6,6 @@
|
|||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:visibility="visible">
|
android:visibility="visible">
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/top_divider_line"
|
|
||||||
android:layout_height="1px"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:background="#353548"
|
|
||||||
android:visibility="gone"/>
|
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager.widget.ViewPager
|
||||||
android:id="@+id/scrPlugin"
|
android:id="@+id/scrPlugin"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
@@ -30,8 +23,6 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="horizontal"/>
|
android:orientation="horizontal"/>
|
||||||
|
|
||||||
<View style="@style/horizontal_light_thin_divider"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -50,6 +41,7 @@
|
|||||||
android:layout_height="44dp"
|
android:layout_height="44dp"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</HorizontalScrollView>
|
</HorizontalScrollView>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<color name="nim_app_color">#FFBC52</color>
|
<color name="nim_app_color">#5BC8F8</color>
|
||||||
<color name="nim_app_color_press">#FFBC52</color>
|
<color name="nim_app_color_press">#5BC8F8</color>
|
||||||
|
|
||||||
<color name="transparent">#00000000</color>
|
<color name="transparent">#00000000</color>
|
||||||
<color name="white">#FFFFFF</color>
|
<color name="white">#FFFFFF</color>
|
||||||
|
@@ -1,61 +0,0 @@
|
|||||||
package com.netease.nim.uikit;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by huangmeng1 on 2018/3/9.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class AndroidBug5497Workaround {
|
|
||||||
|
|
||||||
// For more information, see https://code.google.com/p/android/issues/detail?id=5497
|
|
||||||
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
|
|
||||||
|
|
||||||
public static void assistActivity (Activity activity) {
|
|
||||||
new AndroidBug5497Workaround(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
private View mChildOfContent;
|
|
||||||
private int usableHeightPrevious;
|
|
||||||
private FrameLayout.LayoutParams frameLayoutParams;
|
|
||||||
|
|
||||||
private AndroidBug5497Workaround(final Activity activity) {
|
|
||||||
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
|
|
||||||
mChildOfContent = content.getChildAt(0);
|
|
||||||
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
|
||||||
public void onGlobalLayout() {
|
|
||||||
possiblyResizeChildOfContent(activity);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void possiblyResizeChildOfContent(Activity activity) {
|
|
||||||
int usableHeightNow = computeUsableHeight();
|
|
||||||
if (usableHeightNow != usableHeightPrevious) {
|
|
||||||
int usableHeightSansKeyboard = activity.getWindowManager().getDefaultDisplay().getHeight();
|
|
||||||
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
|
|
||||||
if (heightDifference > (usableHeightSansKeyboard/4)) {
|
|
||||||
// keyboard probably just became visible
|
|
||||||
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
|
|
||||||
} else {
|
|
||||||
// keyboard probably just became hidden
|
|
||||||
frameLayoutParams.height = usableHeightSansKeyboard;
|
|
||||||
}
|
|
||||||
mChildOfContent.requestLayout();
|
|
||||||
usableHeightPrevious = usableHeightNow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int computeUsableHeight() {
|
|
||||||
Rect r = new Rect();
|
|
||||||
mChildOfContent.getWindowVisibleDisplayFrame(r);
|
|
||||||
return (r.bottom - r.top);// 全屏模式下: return r.bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@@ -307,16 +307,6 @@ public class NimUIKit {
|
|||||||
NimUIKitImpl.startP2PSession(context, account);
|
NimUIKitImpl.startP2PSession(context, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 同 {@link NimUIKitImpl#startP2PSession(Context, String)},同时聊天界面打开后,列表跳转至anchor位置
|
|
||||||
*
|
|
||||||
* @param context 上下文
|
|
||||||
* @param account 目标账号
|
|
||||||
* @param anchor 跳转到指定消息的位置,不需要跳转填null
|
|
||||||
*/
|
|
||||||
public static void startP2PSession(Context context, String account, IMMessage anchor) {
|
|
||||||
NimUIKitImpl.startP2PSession(context, account, anchor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开群聊界面,若开发者未设置 {@link NimUIKitImpl#setCommonTeamSessionCustomization(SessionCustomization)},
|
* 打开群聊界面,若开发者未设置 {@link NimUIKitImpl#setCommonTeamSessionCustomization(SessionCustomization)},
|
||||||
|
@@ -1,82 +0,0 @@
|
|||||||
package com.netease.nim.uikit.api.wrapper;
|
|
||||||
|
|
||||||
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.msg.constant.SessionTypeEnum;
|
|
||||||
import com.netease.nimlib.sdk.team.model.Team;
|
|
||||||
import com.netease.nimlib.sdk.uinfo.UserInfoProvider;
|
|
||||||
import com.netease.nimlib.sdk.uinfo.model.UserInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化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.nim_avatar_default;
|
|
||||||
|
|
||||||
if (SessionTypeEnum.P2P == sessionType) {
|
|
||||||
UserInfo user = getUserInfo(sessionId);
|
|
||||||
bm = (user != null) ? NimUIKit.getImageLoaderKit().getNotificationBitmapFromCache(user.getAvatar()) : null;
|
|
||||||
} else if (SessionTypeEnum.Team == sessionType) {
|
|
||||||
Team team = NimUIKit.getTeamProvider().getTeamById(sessionId);
|
|
||||||
bm = (team != null) ? NimUIKit.getImageLoaderKit().getNotificationBitmapFromCache(team.getIcon()) : null;
|
|
||||||
defResId = R.drawable.nim_avatar_group;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bm == null) {
|
|
||||||
Drawable drawable = context.getResources().getDrawable(defResId);
|
|
||||||
if (drawable instanceof BitmapDrawable) {
|
|
||||||
bm = ((BitmapDrawable) drawable).getBitmap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bm;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDisplayNameForMessageNotifier(String account, String sessionId, SessionTypeEnum sessionType) {
|
|
||||||
String nick = null;
|
|
||||||
if (sessionType == SessionTypeEnum.P2P) {
|
|
||||||
nick = NimUIKit.getContactProvider().getAlias(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,44 @@
|
|||||||
|
package com.netease.nim.uikit.business.session.actions;
|
||||||
|
|
||||||
|
import com.netease.nim.uikit.R;
|
||||||
|
import com.netease.nim.uikit.business.session.constant.RequestCode;
|
||||||
|
import com.netease.nim.uikit.business.session.event.ActiveEvent;
|
||||||
|
import com.netease.nim.uikit.common.media.picker.PickImageHelper;
|
||||||
|
import com.netease.nimlib.sdk.chatroom.ChatRoomMessageBuilder;
|
||||||
|
import com.netease.nimlib.sdk.msg.MessageBuilder;
|
||||||
|
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||||
|
import com.netease.nimlib.sdk.msg.model.IMMessage;
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by hzxuwen on 2015/6/12.
|
||||||
|
*/
|
||||||
|
public class CameraAction extends PickImageAction {
|
||||||
|
|
||||||
|
public CameraAction() {
|
||||||
|
super(R.drawable.chat_icon_photo, R.string.input_panel_photo, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick() {
|
||||||
|
PickImageHelper.pickCamera(getActivity(), makeRequestCode(RequestCode.PICK_IMAGE), buildOption());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPicked(File file) {
|
||||||
|
IMMessage message;
|
||||||
|
if (getContainer() != null && getContainer().sessionType == SessionTypeEnum.ChatRoom) {
|
||||||
|
message = ChatRoomMessageBuilder.createChatRoomImageMessage(getAccount(), file, file.getName());
|
||||||
|
} else {
|
||||||
|
message = MessageBuilder.createImageMessage(getAccount(), getSessionType(), file, file.getName());
|
||||||
|
}
|
||||||
|
sendMessage(message);
|
||||||
|
|
||||||
|
EventBus.getDefault().post(new ActiveEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,43 @@
|
|||||||
|
package com.netease.nim.uikit.business.session.actions;
|
||||||
|
|
||||||
|
import com.netease.nim.uikit.R;
|
||||||
|
import com.netease.nim.uikit.business.session.constant.RequestCode;
|
||||||
|
import com.netease.nim.uikit.business.session.event.ActiveEvent;
|
||||||
|
import com.netease.nim.uikit.common.media.picker.PickImageHelper;
|
||||||
|
import com.netease.nimlib.sdk.chatroom.ChatRoomMessageBuilder;
|
||||||
|
import com.netease.nimlib.sdk.msg.MessageBuilder;
|
||||||
|
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
|
||||||
|
import com.netease.nimlib.sdk.msg.model.IMMessage;
|
||||||
|
|
||||||
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by hzxuwen on 2015/6/12.
|
||||||
|
*/
|
||||||
|
public class PhotoAction extends PickImageAction {
|
||||||
|
|
||||||
|
public PhotoAction() {
|
||||||
|
super(R.drawable.chat_icon_photo, R.string.input_panel_photo, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick() {
|
||||||
|
PickImageHelper.pickPhoto(getActivity(), makeRequestCode(RequestCode.PICK_IMAGE), buildOption());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPicked(File file) {
|
||||||
|
IMMessage message;
|
||||||
|
if (getContainer() != null && getContainer().sessionType == SessionTypeEnum.ChatRoom) {
|
||||||
|
message = ChatRoomMessageBuilder.createChatRoomImageMessage(getAccount(), file, file.getName());
|
||||||
|
} else {
|
||||||
|
message = MessageBuilder.createImageMessage(getAccount(), getSessionType(), file, file.getName());
|
||||||
|
}
|
||||||
|
sendMessage(message);
|
||||||
|
|
||||||
|
EventBus.getDefault().post(new ActiveEvent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -25,26 +25,23 @@ import java.io.File;
|
|||||||
*/
|
*/
|
||||||
public abstract class PickImageAction extends BaseAction {
|
public abstract class PickImageAction extends BaseAction {
|
||||||
|
|
||||||
private static final int PICK_IMAGE_COUNT = 9;
|
|
||||||
private static final int PORTRAIT_IMAGE_WIDTH = 720;
|
|
||||||
|
|
||||||
public static final String MIME_JPEG = "image/jpeg";
|
public static final String MIME_JPEG = "image/jpeg";
|
||||||
public static final String JPG = ".jpg";
|
public static final String JPG = ".jpg";
|
||||||
|
private static final int PICK_IMAGE_COUNT = 9;
|
||||||
|
private static final int PORTRAIT_IMAGE_WIDTH = 720;
|
||||||
private boolean multiSelect;
|
private boolean multiSelect;
|
||||||
private boolean crop = false;
|
private boolean crop = false;
|
||||||
|
|
||||||
protected abstract void onPicked(File file);
|
|
||||||
|
|
||||||
protected PickImageAction(int iconResId, int titleId, boolean multiSelect) {
|
protected PickImageAction(int iconResId, int titleId, boolean multiSelect) {
|
||||||
super(iconResId, titleId);
|
super(iconResId, titleId);
|
||||||
this.multiSelect = multiSelect;
|
this.multiSelect = multiSelect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract void onPicked(File file);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick() {
|
public void onClick() {
|
||||||
int requestCode = makeRequestCode(RequestCode.PICK_IMAGE);
|
PickImageHelper.pickImage(getActivity(), makeRequestCode(RequestCode.PICK_IMAGE), buildOption());
|
||||||
showSelector(getTitleId(), requestCode, multiSelect, tempFile());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String tempFile() {
|
private String tempFile() {
|
||||||
@@ -52,20 +49,16 @@ public abstract class PickImageAction extends BaseAction {
|
|||||||
return StorageUtil.getWritePath(filename, StorageType.TYPE_TEMP);
|
return StorageUtil.getWritePath(filename, StorageType.TYPE_TEMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public PickImageHelper.PickImageOption buildOption() {
|
||||||
* 打开图片选择器
|
|
||||||
*/
|
|
||||||
private void showSelector(int titleId, final int requestCode, final boolean multiSelect, final String outPath) {
|
|
||||||
PickImageHelper.PickImageOption option = new PickImageHelper.PickImageOption();
|
PickImageHelper.PickImageOption option = new PickImageHelper.PickImageOption();
|
||||||
option.titleResId = titleId;
|
option.titleResId = getTitleId();
|
||||||
option.multiSelect = multiSelect;
|
option.multiSelect = multiSelect;
|
||||||
option.multiSelectMaxCount = PICK_IMAGE_COUNT;
|
option.multiSelectMaxCount = PICK_IMAGE_COUNT;
|
||||||
option.crop = crop;
|
option.crop = crop;
|
||||||
option.cropOutputImageWidth = PORTRAIT_IMAGE_WIDTH;
|
option.cropOutputImageWidth = PORTRAIT_IMAGE_WIDTH;
|
||||||
option.cropOutputImageHeight = PORTRAIT_IMAGE_WIDTH;
|
option.cropOutputImageHeight = PORTRAIT_IMAGE_WIDTH;
|
||||||
option.outputPath = outPath;
|
option.outputPath = tempFile();
|
||||||
|
return option;
|
||||||
PickImageHelper.pickImage(getActivity(), requestCode, option);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -1,11 +1,8 @@
|
|||||||
package com.netease.nim.uikit.business.session.emoji;
|
package com.netease.nim.uikit.business.session.emoji;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -15,6 +12,8 @@ import android.widget.HorizontalScrollView;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
import com.netease.nim.uikit.R;
|
import com.netease.nim.uikit.R;
|
||||||
import com.netease.nim.uikit.common.ui.imageview.CheckedImageButton;
|
import com.netease.nim.uikit.common.ui.imageview.CheckedImageButton;
|
||||||
import com.netease.nim.uikit.common.util.log.LogUtil;
|
import com.netease.nim.uikit.common.util.log.LogUtil;
|
||||||
@@ -47,9 +46,14 @@ public class EmoticonPickerView extends LinearLayout implements IEmoticonCategor
|
|||||||
private HorizontalScrollView scrollView;
|
private HorizontalScrollView scrollView;
|
||||||
|
|
||||||
private LinearLayout tabView;
|
private LinearLayout tabView;
|
||||||
|
// 添加各个tab按钮
|
||||||
|
OnClickListener tabCheckListener = new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
onEmoticonBtnChecked(v.getId());
|
||||||
|
}
|
||||||
|
};
|
||||||
private int categoryIndex;
|
private int categoryIndex;
|
||||||
|
|
||||||
private Handler uiHandler;
|
private Handler uiHandler;
|
||||||
|
|
||||||
public EmoticonPickerView(Context context) {
|
public EmoticonPickerView(Context context) {
|
||||||
@@ -64,17 +68,14 @@ public class EmoticonPickerView extends LinearLayout implements IEmoticonCategor
|
|||||||
init(context);
|
init(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
|
||||||
public EmoticonPickerView(Context context, AttributeSet attrs, int defStyle) {
|
public EmoticonPickerView(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
|
|
||||||
init(context);
|
init(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init(Context context) {
|
private void init(Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.uiHandler = new Handler(context.getMainLooper());
|
this.uiHandler = new Handler(context.getMainLooper());
|
||||||
|
|
||||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
inflater.inflate(R.layout.nim_emoji_layout, this);
|
inflater.inflate(R.layout.nim_emoji_layout, this);
|
||||||
}
|
}
|
||||||
@@ -91,41 +92,26 @@ public class EmoticonPickerView extends LinearLayout implements IEmoticonCategor
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void show(IEmoticonSelectedListener listener) {
|
public void show(IEmoticonSelectedListener listener) {
|
||||||
setListener(listener);
|
this.listener = listener;
|
||||||
|
|
||||||
if (loaded)
|
if (loaded)
|
||||||
return;
|
return;
|
||||||
loadStickers();
|
loadStickers();
|
||||||
loaded = true;
|
loaded = true;
|
||||||
|
if (!withSticker) {
|
||||||
show();
|
showEmojiView();
|
||||||
}
|
|
||||||
|
|
||||||
public void setListener(IEmoticonSelectedListener listener) {
|
|
||||||
if (listener != null) {
|
|
||||||
this.listener = listener;
|
|
||||||
} else {
|
} else {
|
||||||
LogUtil.i("sticker", "listener is null");
|
onEmoticonBtnChecked(0);
|
||||||
|
setSelectedVisible(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setupEmojView() {
|
protected void setupEmojView() {
|
||||||
currentEmojiPage = (ViewPager) findViewById(R.id.scrPlugin);
|
currentEmojiPage = findViewById(R.id.scrPlugin);
|
||||||
pageNumberLayout = (LinearLayout) findViewById(R.id.layout_scr_bottom);
|
pageNumberLayout = findViewById(R.id.layout_scr_bottom);
|
||||||
tabView = (LinearLayout) findViewById(R.id.emoj_tab_view);
|
tabView = findViewById(R.id.emoj_tab_view);
|
||||||
scrollView = (HorizontalScrollView) findViewById(R.id.emoj_tab_view_container);
|
scrollView = findViewById(R.id.emoj_tab_view_container);
|
||||||
|
|
||||||
findViewById(R.id.top_divider_line).setVisibility(View.VISIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加各个tab按钮
|
|
||||||
OnClickListener tabCheckListener = new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
onEmoticonBtnChecked(v.getId());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void loadStickers() {
|
private void loadStickers() {
|
||||||
if (!withSticker) {
|
if (!withSticker) {
|
||||||
scrollView.setVisibility(View.GONE);
|
scrollView.setVisibility(View.GONE);
|
||||||
@@ -151,7 +137,6 @@ public class EmoticonPickerView extends LinearLayout implements IEmoticonCategor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private CheckedImageButton addEmoticonTabBtn(int index, OnClickListener listener) {
|
private CheckedImageButton addEmoticonTabBtn(int index, OnClickListener listener) {
|
||||||
CheckedImageButton emotBtn = new CheckedImageButton(context);
|
CheckedImageButton emotBtn = new CheckedImageButton(context);
|
||||||
emotBtn.setNormalBkResId(R.drawable.nim_sticker_button_background_normal_layer_list);
|
emotBtn.setNormalBkResId(R.drawable.nim_sticker_button_background_normal_layer_list);
|
||||||
@@ -232,19 +217,6 @@ public class EmoticonPickerView extends LinearLayout implements IEmoticonCategor
|
|||||||
gifView.showEmojis();
|
gifView.showEmojis();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void show() {
|
|
||||||
if (listener == null) {
|
|
||||||
LogUtil.i("sticker", "show picker view when listener is null");
|
|
||||||
}
|
|
||||||
if (!withSticker) {
|
|
||||||
showEmojiView();
|
|
||||||
} else {
|
|
||||||
onEmoticonBtnChecked(0);
|
|
||||||
setSelectedVisible(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void setSelectedVisible(final int index) {
|
private void setSelectedVisible(final int index) {
|
||||||
final Runnable runnable = new Runnable() {
|
final Runnable runnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@@ -18,6 +18,60 @@ import org.greenrobot.eventbus.EventBus;
|
|||||||
*/
|
*/
|
||||||
public class PickImageHelper {
|
public class PickImageHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开图片选择器
|
||||||
|
*/
|
||||||
|
public static void pickImage(final Context context, final int requestCode, final PickImageOption option) {
|
||||||
|
if (context == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomAlertDialog dialog = new CustomAlertDialog(context);
|
||||||
|
dialog.setTitle(option.titleResId);
|
||||||
|
|
||||||
|
dialog.addItem(context.getString(R.string.input_panel_take), () -> pickCamera(context, requestCode, option));
|
||||||
|
|
||||||
|
dialog.addItem(context.getString(R.string.choose_from_photo_album), () -> pickPhoto(context, requestCode, option));
|
||||||
|
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开图片选择器
|
||||||
|
*/
|
||||||
|
public static void pickPhoto(final Context context, final int requestCode, final PickImageOption option) {
|
||||||
|
NimImageActionEvent event = new NimImageActionEvent();
|
||||||
|
event.setSuccess(o -> {
|
||||||
|
int from = PickImageActivity.FROM_LOCAL;
|
||||||
|
if (!option.crop) {
|
||||||
|
PickImageActivity.start((Activity) context, requestCode, from, option.outputPath, option.multiSelect,
|
||||||
|
option.multiSelectMaxCount, true, false, 0, 0);
|
||||||
|
} else {
|
||||||
|
PickImageActivity.start((Activity) context, requestCode, from, option.outputPath, false, 1,
|
||||||
|
false, true, option.cropOutputImageWidth, option.cropOutputImageHeight);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
EventBus.getDefault().post(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开相机发送图片
|
||||||
|
*/
|
||||||
|
public static void pickCamera(final Context context, final int requestCode, final PickImageOption option) {
|
||||||
|
NimImageActionEvent event = new NimImageActionEvent();
|
||||||
|
event.setSuccess(o -> {
|
||||||
|
int from = PickImageActivity.FROM_CAMERA;
|
||||||
|
if (!option.crop) {
|
||||||
|
PickImageActivity.start((Activity) context, requestCode, from, option.outputPath, option.multiSelect, 1,
|
||||||
|
true, false, 0, 0);
|
||||||
|
} else {
|
||||||
|
PickImageActivity.start((Activity) context, requestCode, from, option.outputPath, false, 1,
|
||||||
|
false, true, option.cropOutputImageWidth, option.cropOutputImageHeight);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
EventBus.getDefault().post(event);
|
||||||
|
}
|
||||||
|
|
||||||
public static class PickImageOption {
|
public static class PickImageOption {
|
||||||
/**
|
/**
|
||||||
* 图片选择器标题
|
* 图片选择器标题
|
||||||
@@ -55,53 +109,5 @@ public class PickImageHelper {
|
|||||||
public String outputPath = StorageUtil.getWritePath(StringUtil.get32UUID() + ".jpg", StorageType.TYPE_TEMP);
|
public String outputPath = StorageUtil.getWritePath(StringUtil.get32UUID() + ".jpg", StorageType.TYPE_TEMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 打开图片选择器
|
|
||||||
*/
|
|
||||||
public static void pickImage(final Context context, final int requestCode, final PickImageOption option) {
|
|
||||||
if (context == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomAlertDialog dialog = new CustomAlertDialog(context);
|
|
||||||
dialog.setTitle(option.titleResId);
|
|
||||||
|
|
||||||
dialog.addItem(context.getString(R.string.input_panel_take), new CustomAlertDialog.onSeparateItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick() {
|
|
||||||
NimImageActionEvent event = new NimImageActionEvent();
|
|
||||||
event.setSuccess(o -> {
|
|
||||||
int from = PickImageActivity.FROM_CAMERA;
|
|
||||||
if (!option.crop) {
|
|
||||||
PickImageActivity.start((Activity) context, requestCode, from, option.outputPath, option.multiSelect, 1,
|
|
||||||
true, false, 0, 0);
|
|
||||||
} else {
|
|
||||||
PickImageActivity.start((Activity) context, requestCode, from, option.outputPath, false, 1,
|
|
||||||
false, true, option.cropOutputImageWidth, option.cropOutputImageHeight);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
EventBus.getDefault().post(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.addItem(context.getString(R.string.choose_from_photo_album), new CustomAlertDialog.onSeparateItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick() {
|
|
||||||
NimImageActionEvent event = new NimImageActionEvent();
|
|
||||||
event.setSuccess(o -> {
|
|
||||||
int from = PickImageActivity.FROM_LOCAL;
|
|
||||||
if (!option.crop) {
|
|
||||||
PickImageActivity.start((Activity) context, requestCode, from, option.outputPath, option.multiSelect,
|
|
||||||
option.multiSelectMaxCount, true, false, 0, 0);
|
|
||||||
} else {
|
|
||||||
PickImageActivity.start((Activity) context, requestCode, from, option.outputPath, false, 1,
|
|
||||||
false, true, option.cropOutputImageWidth, option.cropOutputImageHeight);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
EventBus.getDefault().post(event);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,36 +0,0 @@
|
|||||||
package com.netease.nim.uikit.impl.preference;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
|
|
||||||
import com.netease.nim.uikit.api.NimUIKit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by hzxuwen on 2015/10/21.
|
|
||||||
*/
|
|
||||||
public class UserPreferences {
|
|
||||||
|
|
||||||
private final static String KEY_EARPHONE_MODE = "KEY_EARPHONE_MODE";
|
|
||||||
|
|
||||||
public static void setEarPhoneModeEnable(boolean on) {
|
|
||||||
saveBoolean(KEY_EARPHONE_MODE, on);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isEarPhoneModeEnable() {
|
|
||||||
return getBoolean(KEY_EARPHONE_MODE, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
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.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static SharedPreferences getSharedPreferences() {
|
|
||||||
return NimUIKit.getContext().getSharedPreferences("UIKit." + NimUIKit.getAccount(), Context.MODE_PRIVATE);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,204 +0,0 @@
|
|||||||
package com.netease.nim.uikit.support.permission;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Build;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class BaseMPermission {
|
|
||||||
|
|
||||||
private static final String TAG = "MPermission";
|
|
||||||
|
|
||||||
public enum MPermissionResultEnum {
|
|
||||||
GRANTED, DENIED, DENIED_NEVER_ASK_AGAIN
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean isOverMarshmallow() {
|
|
||||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Activity getActivity(Object object) {
|
|
||||||
if (object instanceof Fragment) {
|
|
||||||
return ((Fragment) object).getActivity();
|
|
||||||
} else if (object instanceof Activity) {
|
|
||||||
return (Activity) object;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取权限请求结果
|
|
||||||
*/
|
|
||||||
public static List<MPermissionResultEnum> getPermissionResult(Activity activity, String[] permissions) {
|
|
||||||
return findPermissionResult(activity, permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<MPermissionResultEnum> getPermissionResult(Fragment fragment, String[] permissions) {
|
|
||||||
return findPermissionResult(fragment.getActivity(), permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(value = Build.VERSION_CODES.M)
|
|
||||||
private static List<MPermissionResultEnum> findPermissionResult(Activity activity, String... permissions) {
|
|
||||||
boolean overM = isOverMarshmallow();
|
|
||||||
List<MPermissionResultEnum> result = new ArrayList<>();
|
|
||||||
for (String p : permissions) {
|
|
||||||
if (overM) {
|
|
||||||
if (activity.checkSelfPermission(p) == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
result.add(MPermissionResultEnum.GRANTED);
|
|
||||||
} else {
|
|
||||||
if (!activity.shouldShowRequestPermissionRationale(p)) {
|
|
||||||
result.add(MPermissionResultEnum.DENIED_NEVER_ASK_AGAIN);
|
|
||||||
} else {
|
|
||||||
result.add(MPermissionResultEnum.DENIED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.add(MPermissionResultEnum.GRANTED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有被未被授权的权限
|
|
||||||
*/
|
|
||||||
public static List<String> getDeniedPermissions(Activity activity, String[] permissions) {
|
|
||||||
return findDeniedPermissions(activity, permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> getDeniedPermissions(Fragment fragment, String[] permissions) {
|
|
||||||
return findDeniedPermissions(fragment.getActivity(), permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(value = Build.VERSION_CODES.M)
|
|
||||||
static List<String> findDeniedPermissions(Activity activity, String... permissions) {
|
|
||||||
if (!isOverMarshmallow()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> denyPermissions = new ArrayList<>();
|
|
||||||
for (String value : permissions) {
|
|
||||||
if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
denyPermissions.add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return denyPermissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取被拒绝且勾选不再询问的权限
|
|
||||||
* 请在请求权限结果回调中使用,因为从未请求过的权限也会被认为是该结果集
|
|
||||||
*/
|
|
||||||
public static List<String> getNeverAskAgainPermissions(Activity activity, String[] permissions) {
|
|
||||||
return findNeverAskAgainPermissions(activity, permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> getNeverAskAgainPermissions(Fragment fragment, String[] permissions) {
|
|
||||||
return findNeverAskAgainPermissions(fragment.getActivity(), permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(value = Build.VERSION_CODES.M)
|
|
||||||
private static List<String> findNeverAskAgainPermissions(Activity activity, String... permissions) {
|
|
||||||
if (!isOverMarshmallow()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> neverAskAgainPermission = new ArrayList<>();
|
|
||||||
for (String value : permissions) {
|
|
||||||
if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED &&
|
|
||||||
!activity.shouldShowRequestPermissionRationale(value)) {
|
|
||||||
// 拒绝&不要需要解释了(用户勾选了不再询问)
|
|
||||||
// 坑爹:第一次不做任何设置,返回值也是false。建议在权限授权结果里判断!!!
|
|
||||||
neverAskAgainPermission.add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return neverAskAgainPermission;
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(value = Build.VERSION_CODES.M)
|
|
||||||
static boolean hasNeverAskAgainPermission(Activity activity, List<String> permission) {
|
|
||||||
if (!isOverMarshmallow()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String value : permission) {
|
|
||||||
if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED &&
|
|
||||||
!activity.shouldShowRequestPermissionRationale(value)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取被拒绝但没有勾选不再询问的权限(可以继续申请,会继续弹框)
|
|
||||||
*/
|
|
||||||
public static List<String> getDeniedPermissionsWithoutNeverAskAgain(Activity activity, String[] permissions) {
|
|
||||||
return findDeniedPermissionWithoutNeverAskAgain(activity, permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> getDeniedPermissionsWithoutNeverAskAgain(Fragment fragment, String[] permissions) {
|
|
||||||
return findDeniedPermissionWithoutNeverAskAgain(fragment.getActivity(), permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(value = Build.VERSION_CODES.M)
|
|
||||||
private static List<String> findDeniedPermissionWithoutNeverAskAgain(Activity activity, String... permission) {
|
|
||||||
if (!isOverMarshmallow()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> denyPermissions = new ArrayList<>();
|
|
||||||
for (String value : permission) {
|
|
||||||
if (activity.checkSelfPermission(value) != PackageManager.PERMISSION_GRANTED &&
|
|
||||||
activity.shouldShowRequestPermissionRationale(value)) {
|
|
||||||
denyPermissions.add(value); // 上次申请被用户拒绝了
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return denyPermissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log专用
|
|
||||||
*/
|
|
||||||
public static void printMPermissionResult(boolean preRequest, Activity activity, String[] permissions) {
|
|
||||||
Log.i(TAG, "----- MPermission result " + (preRequest ? "before" : "after") + " request:");
|
|
||||||
List<BaseMPermission.MPermissionResultEnum> result = getPermissionResult(activity, permissions);
|
|
||||||
int i = 0;
|
|
||||||
for (BaseMPermission.MPermissionResultEnum p : result) {
|
|
||||||
Log.i(TAG, "* MPermission=" + permissions[i++] + ", result=" + p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static String toString(List<String> permission) {
|
|
||||||
if (permission == null || permission.isEmpty()) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return toString(permission.toArray(new String[permission.size()]));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String toString(String[] permission) {
|
|
||||||
if (permission == null || permission.length <= 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (String p : permission) {
|
|
||||||
sb.append(p.replaceFirst("android.permission.", ""));
|
|
||||||
sb.append(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.deleteCharAt(sb.length() - 1);
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,170 +0,0 @@
|
|||||||
package com.netease.nim.uikit.support.permission;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.os.Build;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
|
|
||||||
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 java.lang.annotation.Annotation;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MPermission extends BaseMPermission {
|
|
||||||
|
|
||||||
private int requestCode;
|
|
||||||
private String[] permissions;
|
|
||||||
private Object object; // activity or fragment
|
|
||||||
|
|
||||||
private MPermission(Object object) {
|
|
||||||
this.object = object;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MPermission with(Activity activity) {
|
|
||||||
return new MPermission(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MPermission with(Fragment fragment) {
|
|
||||||
return new MPermission(fragment);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MPermission setRequestCode(int requestCode) {
|
|
||||||
this.requestCode = requestCode;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MPermission permissions(String... permissions) {
|
|
||||||
this.permissions = permissions;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ********************* request *********************
|
|
||||||
*/
|
|
||||||
|
|
||||||
@TargetApi(value = Build.VERSION_CODES.M)
|
|
||||||
public void request() {
|
|
||||||
doRequestPermissions(object, requestCode, permissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(value = Build.VERSION_CODES.M)
|
|
||||||
private static void doRequestPermissions(Object object, int requestCode, String[] permissions) {
|
|
||||||
if (!isOverMarshmallow()) {
|
|
||||||
doExecuteSuccess(object, requestCode);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> deniedPermissions = findDeniedPermissions(getActivity(object), permissions);
|
|
||||||
if (deniedPermissions != null && deniedPermissions.size() > 0) {
|
|
||||||
if (object instanceof Activity) {
|
|
||||||
((Activity) object).requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
|
|
||||||
} else if (object instanceof Fragment) {
|
|
||||||
((Fragment) object).requestPermissions(deniedPermissions.toArray(new String[deniedPermissions.size()]), requestCode);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(object.getClass().getName() + " is not supported");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
doExecuteSuccess(object, requestCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ********************* on result *********************
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static void onRequestPermissionsResult(Activity activity, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
|
||||||
dispatchResult(activity, requestCode, permissions, grantResults);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void onRequestPermissionsResult(Fragment fragment, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
|
||||||
dispatchResult(fragment, requestCode, permissions, grantResults);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void dispatchResult(Object obj, int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
|
||||||
List<String> deniedPermissions = new ArrayList<>();
|
|
||||||
for (int i = 0; i < grantResults.length; i++) {
|
|
||||||
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
deniedPermissions.add(permissions[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deniedPermissions.size() > 0) {
|
|
||||||
if (hasNeverAskAgainPermission(getActivity(obj), deniedPermissions)) {
|
|
||||||
doExecuteFailAsNeverAskAgain(obj, requestCode);
|
|
||||||
} else {
|
|
||||||
doExecuteFail(obj, requestCode);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
doExecuteSuccess(obj, requestCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ********************* reflect execute result *********************
|
|
||||||
*/
|
|
||||||
|
|
||||||
private static void doExecuteSuccess(Object activity, int requestCode) {
|
|
||||||
executeMethod(activity, findMethodWithRequestCode(activity.getClass(), OnMPermissionGranted.class, requestCode));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void doExecuteFail(Object activity, int requestCode) {
|
|
||||||
executeMethod(activity, findMethodWithRequestCode(activity.getClass(), OnMPermissionDenied.class, requestCode));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void doExecuteFailAsNeverAskAgain(Object activity, int requestCode) {
|
|
||||||
executeMethod(activity, findMethodWithRequestCode(activity.getClass(), OnMPermissionNeverAskAgain.class, requestCode));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <A extends Annotation> Method findMethodWithRequestCode(Class clazz, Class<A> annotation, int
|
|
||||||
requestCode) {
|
|
||||||
for (Method method : clazz.getDeclaredMethods()) {
|
|
||||||
if (method.getAnnotation(annotation) != null &&
|
|
||||||
isEqualRequestCodeFromAnnotation(method, annotation, requestCode)) {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isEqualRequestCodeFromAnnotation(Method m, Class clazz, int requestCode) {
|
|
||||||
if (clazz.equals(OnMPermissionDenied.class)) {
|
|
||||||
return requestCode == m.getAnnotation(OnMPermissionDenied.class).value();
|
|
||||||
} else if (clazz.equals(OnMPermissionGranted.class)) {
|
|
||||||
return requestCode == m.getAnnotation(OnMPermissionGranted.class).value();
|
|
||||||
} else if (clazz.equals(OnMPermissionNeverAskAgain.class)) {
|
|
||||||
return requestCode == m.getAnnotation(OnMPermissionNeverAskAgain.class).value();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ********************* reflect execute method *********************
|
|
||||||
*/
|
|
||||||
|
|
||||||
private static void executeMethod(Object activity, Method executeMethod) {
|
|
||||||
executeMethodWithParam(activity, executeMethod, new Object[]{});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void executeMethodWithParam(Object activity, Method executeMethod, Object... args) {
|
|
||||||
if (executeMethod != null) {
|
|
||||||
try {
|
|
||||||
if (!executeMethod.isAccessible()) {
|
|
||||||
executeMethod.setAccessible(true);
|
|
||||||
}
|
|
||||||
executeMethod.invoke(activity, args);
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
package com.netease.nim.uikit.support.permission.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* register a method invoked when permission requests are denied without check never ask again.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
public @interface OnMPermissionDenied {
|
|
||||||
int value();
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
package com.netease.nim.uikit.support.permission.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* register a method invoked when permission requests are succeeded.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
public @interface OnMPermissionGranted {
|
|
||||||
int value();
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
package com.netease.nim.uikit.support.permission.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* register some methods handling the user's choice to permanently deny permissions checking never ask again.
|
|
||||||
*/
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Target(ElementType.METHOD)
|
|
||||||
public @interface OnMPermissionNeverAskAgain {
|
|
||||||
int value();
|
|
||||||
}
|
|
Reference in New Issue
Block a user