diff --git a/build.gradle b/build.gradle
index 8e64390d..cfa73f87 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,9 +3,10 @@
buildscript {
repositories {
jcenter()
+ google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.3.3'
+ classpath 'com.android.tools.build:gradle:3.3.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -20,6 +21,7 @@ allprojects {
url "https://oss.sonatype.org/content/repositories/snapshots/"
}
maven { url "https://jitpack.io" }
+ google()
}
}
diff --git a/chatapp/ChangeLog.md b/chatapp/ChangeLog.md
new file mode 100644
index 00000000..ac092de5
--- /dev/null
+++ b/chatapp/ChangeLog.md
@@ -0,0 +1,10 @@
+### JChat v2.3.0
+
+#### ChangeLog
+
+##### BugFix:
++ 修复表情库无法使用问题
++ 修复用户反馈的一些其他bug
+
+##### NewFeature
++ 新增聊天室功能
\ No newline at end of file
diff --git a/chatapp/build.gradle b/chatapp/build.gradle
index 975c19c5..78d14de1 100644
--- a/chatapp/build.gradle
+++ b/chatapp/build.gradle
@@ -1,17 +1,16 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 25
- buildToolsVersion "25.0.1"
+ compileSdkVersion 26
+ buildToolsVersion '28.0.3'
defaultConfig {
applicationId "io.jchat.android"
minSdkVersion 18
targetSdkVersion 23
versionCode 61
- versionName "2.2.0"
+ versionName "2.3.0"
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-
manifestPlaceholders = [
JPUSH_PKGNAME : applicationId,
JPUSH_APPKEY : "4f7aef34fb361292c566a1cd", //JPush上注册的包名对应的appkey.
@@ -20,9 +19,8 @@ android {
ndk {
//选择要添加的对应cpu类型的.so库。
- abiFilters 'armeabi', 'armeabi-v7a', 'armeabi-v8a','x86', 'x86_64', 'mips', 'mips64'
+ abiFilters 'armeabi', 'armeabi-v7a', 'armeabi-v8a', 'x86', 'x86_64', 'mips', 'mips64'
}
-
}
buildTypes {
release {
@@ -38,31 +36,42 @@ android {
}
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false
-
-
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ lintOptions {
+ disable 'GoogleAppIndexingWarning'
+ }
}
dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
- compile 'com.android.support:multidex:1.0.1'
- compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
- compile 'com.android.support:appcompat-v7:23.4.0'
- compile 'com.android.support:recyclerview-v7:23.1.0'
- compile 'com.android.support:design:23.1.0'
- testCompile 'junit:junit:4.12'
- compile 'com.jakewharton:butterknife:7.0.1'
- compile 'com.github.bumptech.glide:glide:3.6.1'
- compile 'com.github.w446108264:AndroidEmoji:1.0.0'
- compile 'com.github.chrisbanes.photoview:library:1.2.4'
- compile 'com.facebook.fresco:fresco:0.8.1'
- compile 'org.greenrobot:eventbus:3.0.0'
- compile 'io.reactivex:rxandroid:1.2.1'
- compile project(':reclib-qq')
- compile project(':reclib-testemoticons')
- compile 'com.contrarywind:Android-PickerView:3.2.4'
- compile 'cn.jiguang.sdk:jmessage:2.7.0' // 此处以JMessage 2.7.0 版本为例。
- compile 'cn.jiguang.sdk:jcore:1.2.3' // 此处以JCore 1.2.3 版本为例。
+ implementation 'com.android.support:multidex:1.0.1'
+ implementation 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
+ implementation 'com.android.support:appcompat-v7:26.1.0'
+ implementation 'com.android.support:recyclerview-v7:26.1.0'
+ implementation 'com.android.support:design:26.1.0'
+ testImplementation 'junit:junit:4.12'
+ implementation 'com.jakewharton:butterknife:7.0.1'
+ annotationProcessor 'com.jakewharton:butterknife:7.0.1'
+ implementation 'com.github.bumptech.glide:glide:3.6.1'
+ implementation 'com.github.chrisbanes.photoview:library:1.2.4'
+ implementation 'com.facebook.fresco:fresco:0.8.1'
+ implementation 'org.greenrobot:eventbus:3.0.0'
+ implementation 'io.reactivex:rxandroid:1.2.1'
+ implementation project(':emoji')
+ implementation project(':reclib-qq')
+ implementation project(':reclib-testemoticons')
+ implementation 'com.contrarywind:Android-PickerView:3.2.4'
+ implementation 'com.yanzhenjie:permission:1.1.2'
+ implementation 'cn.jiguang.sdk:jmessage:2.9.0' // 此处以J
+ implementation 'cn.jiguang.sdk:jcore:2.0.0'
+ implementation 'org.greenrobot:eventbus:3.1.1'
+ implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-26'
+ implementation 'com.github.mtotschnig:StickyListHeaders:2.7.1'
}
diff --git a/chatapp/src/main/AndroidManifest.xml b/chatapp/src/main/AndroidManifest.xml
index 10a86d91..4f8aa7ac 100644
--- a/chatapp/src/main/AndroidManifest.xml
+++ b/chatapp/src/main/AndroidManifest.xml
@@ -1,12 +1,10 @@
-
+
-
-
+ android:protectionLevel="signature"/>
@@ -21,8 +19,7 @@
-
-
+
@@ -33,30 +30,42 @@
+
+
+
+
+
+
+ android:value="jiguang.chat.database.UserEntry, jiguang.chat.database.FriendEntry, jiguang.chat.database.FriendRecommendEntry, jiguang.chat.database.GroupApplyEntry , jiguang.chat.database.RefuseGroupEntry"/>
-
+ android:value="4"/>
+
+
+
+
+
+
-
-
-
+
@@ -73,8 +82,7 @@
+ android:screenOrientation="portrait"/>
+ android:theme="@style/BaseThemes"
+ android:windowSoftInputMode="stateVisible"/>
-
-
+
-
-
-
-
-
-
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:exported="false"/>
-
+
\ No newline at end of file
diff --git a/chatapp/src/main/java/jiguang/chat/MyService.java b/chatapp/src/main/java/jiguang/chat/MyService.java
new file mode 100644
index 00000000..bfe28024
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/MyService.java
@@ -0,0 +1,6 @@
+package jiguang.chat;
+
+import cn.jpush.android.service.JCommonService;
+
+public class MyService extends JCommonService {
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/ApplyGroupInfoActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ApplyGroupInfoActivity.java
new file mode 100644
index 00000000..e04e46a8
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/ApplyGroupInfoActivity.java
@@ -0,0 +1,148 @@
+package jiguang.chat.activity;
+
+import android.app.Dialog;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetUserInfoCallback;
+import cn.jpush.im.android.api.model.UserInfo;
+import jiguang.chat.R;
+import jiguang.chat.application.JGApplication;
+import jiguang.chat.database.GroupApplyEntry;
+import jiguang.chat.database.UserEntry;
+import jiguang.chat.utils.DialogCreator;
+
+/**
+ * Created by ${chenyn} on 2017/11/22.
+ */
+
+public class ApplyGroupInfoActivity extends BaseActivity {
+
+ private ImageView mIv_avatar;
+ private TextView mTv_nickName;
+ private TextView mTv_sign;
+ private TextView mTv_additionalMsg;
+ private TextView mTv_userName;
+ private TextView mTv_gender;
+ private TextView mTv_birthday;
+ private TextView mTv_address;
+ private Button mBtn_refusal;
+ private Button mBtn_agree;
+ private String name;
+ private LinearLayout mBtn_refuseAgree;
+ private LinearLayout mLl_state;
+ private TextView mTv_state;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_apply_group_info);
+
+ initView();
+ initData();
+
+ }
+
+ private void initView() {
+ initTitle(true, true, "返回", "详细资料", false, "");
+
+ mIv_avatar = (ImageView) findViewById(R.id.iv_avatar);
+ mTv_nickName = (TextView) findViewById(R.id.tv_nickName);
+ mTv_sign = (TextView) findViewById(R.id.tv_sign);
+ mTv_additionalMsg = (TextView) findViewById(R.id.tv_additionalMsg);
+ mTv_userName = (TextView) findViewById(R.id.tv_userName);
+ mTv_gender = (TextView) findViewById(R.id.tv_gender);
+ mTv_birthday = (TextView) findViewById(R.id.tv_birthday);
+ mTv_address = (TextView) findViewById(R.id.tv_address);
+
+ mBtn_refuseAgree = (LinearLayout) findViewById(R.id.btn_refuseAgree);
+ mBtn_refusal = (Button) findViewById(R.id.btn_refusal);
+ mBtn_agree = (Button) findViewById(R.id.btn_agree);
+
+ mLl_state = (LinearLayout) findViewById(R.id.ll_state);
+ mTv_state = (TextView) findViewById(R.id.tv_state);
+ }
+
+ private void initData() {
+
+ UserEntry user = JGApplication.getUserEntry();
+ String toName = getIntent().getStringExtra("toName");
+ String reason = getIntent().getStringExtra("reason");
+ GroupApplyEntry entry = GroupApplyEntry.getEntry(user, toName, JMessageClient.getMyInfo().getAppKey());
+
+ if (entry.btnState == 0) {
+ mBtn_refuseAgree.setVisibility(View.VISIBLE);
+ mLl_state.setVisibility(View.GONE);
+ } else if (entry.btnState == 1) {
+ mBtn_refuseAgree.setVisibility(View.GONE);
+ mLl_state.setVisibility(View.VISIBLE);
+ mTv_state.setText("已同意");
+ } else {
+ mBtn_refuseAgree.setVisibility(View.GONE);
+ mLl_state.setVisibility(View.VISIBLE);
+ mTv_state.setText("已拒绝");
+ }
+
+ mTv_additionalMsg.setText(reason);
+ Dialog dialog = DialogCreator.createLoadingDialog(ApplyGroupInfoActivity.this, "正在加载...");
+ dialog.show();
+ JMessageClient.getUserInfo(toName, new GetUserInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, UserInfo userInfo) {
+ dialog.dismiss();
+ if (i == 0) {
+ if (userInfo.getAvatar() != null) {
+ mIv_avatar.setImageBitmap(BitmapFactory.decodeFile(userInfo.getAvatarFile().getPath()));
+ }
+
+ mTv_nickName.setText(userInfo.getNickname());
+ mTv_sign.setText(userInfo.getSignature());
+ mTv_userName.setText(userInfo.getUserName());
+ UserInfo.Gender gender = userInfo.getGender();
+ if (gender.equals(UserInfo.Gender.male)) {
+ name = "男";
+ } else if (gender.equals(UserInfo.Gender.female)) {
+ name = "女";
+ } else {
+ name = "保密";
+ }
+ mTv_gender.setText(name);
+
+ mTv_address.setText(userInfo.getRegion());
+ mTv_birthday.setText(getBirthday(userInfo));
+ }
+ }
+ });
+
+ mBtn_refusal.setOnClickListener(v -> {
+ entry.btnState = 2;
+ entry.save();
+ finish();
+ });
+
+ mBtn_agree.setOnClickListener(v -> {
+ entry.btnState = 1;
+ entry.save();
+ finish();
+ });
+
+ }
+
+ public String getBirthday(UserInfo info) {
+ long birthday = info.getBirthday();
+ Date date = new Date(birthday);
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+ return dateFormat.format(date);
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/BaseActivity.java b/chatapp/src/main/java/jiguang/chat/activity/BaseActivity.java
index aaf0ed2a..dec5fa2d 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/BaseActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/BaseActivity.java
@@ -69,6 +69,12 @@ public void initTitle(boolean returnBtn, boolean titleLeftDesc, String titleLeft
mReturn_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
+ InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm.isActive() && getCurrentFocus() != null) {
+ if (getCurrentFocus().getWindowToken() != null) {
+ imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+ }
+ }
finish();
}
});
diff --git a/chatapp/src/main/java/jiguang/chat/activity/BrowserViewPagerActivity.java b/chatapp/src/main/java/jiguang/chat/activity/BrowserViewPagerActivity.java
index f62bfddd..ef4d38ae 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/BrowserViewPagerActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/BrowserViewPagerActivity.java
@@ -36,13 +36,16 @@
import java.lang.ref.WeakReference;
import java.text.NumberFormat;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
+import java.util.logging.Logger;
import cn.jpush.im.android.api.JMessageClient;
import cn.jpush.im.android.api.callback.DownloadCompletionCallback;
import cn.jpush.im.android.api.callback.ProgressUpdateCallback;
import cn.jpush.im.android.api.content.ImageContent;
import cn.jpush.im.android.api.enums.ContentType;
+import cn.jpush.im.android.api.enums.ConversationType;
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.Message;
import jiguang.chat.R;
@@ -98,6 +101,9 @@ public class BrowserViewPagerActivity extends BaseActivity {
private final static int GET_NEXT_PAGE_OF_PICTURE = 0x2002;
private final static int SET_CURRENT_POSITION = 0x2003;
private Dialog mDialog;
+ public final static String MSG_JSON = "msg_json";
+ public final static String MSG_LIST_JSON = "msg_list_json";
+ private List messages = new ArrayList<>();
/**
@@ -128,17 +134,25 @@ public void onCreate(Bundle savedInstanceState) {
backgroundThread.start();
mBackgroundHandler = new BackgroundHandler(backgroundThread.getLooper());
final Intent intent = this.getIntent();
- long groupId = intent.getLongExtra(JGApplication.GROUP_ID, 0);
+ ConversationType conversationType = (ConversationType) intent.getSerializableExtra(JGApplication.CONV_TYPE);
+ String targetId = intent.getStringExtra(JGApplication.TARGET_ID);
String targetAppKey = intent.getStringExtra(JGApplication.TARGET_APP_KEY);
- mMessageId = intent.getIntExtra("msgId", 0);
- if (groupId != 0) {
- mConv = JMessageClient.getGroupConversation(groupId);
- } else {
- String targetId = intent.getStringExtra(JGApplication.TARGET_ID);
- if (targetId != null) {
- mConv = JMessageClient.getSingleConversation(targetId, targetAppKey);
+ if (conversationType != null) {
+ switch (conversationType) {
+ case single:
+ mConv = JMessageClient.getSingleConversation(targetId, targetAppKey);
+ break;
+ case group:
+ mConv = JMessageClient.getGroupConversation(Long.valueOf(targetId));
+ break;
+ case chatroom:
+ mConv = JMessageClient.getChatRoomConversation(Long.valueOf(targetId));
+ break;
+ default:
+ break;
}
}
+ mMessageId = intent.getIntExtra("msgId", 0);
mStart = intent.getIntExtra("msgCount", 0);
mPosition = intent.getIntExtra(JGApplication.POSITION, 0);
mFromChatActivity = intent.getBooleanExtra("fromChatActivity", true);
@@ -416,7 +430,11 @@ public void onPageScrolled(final int i, float v, int i2) {
@Override
public void onPageSelected(final int i) {
if (mFromChatActivity) {
- mMsg = mConv.getMessage(mMsgIdList.get(i));
+ if (mConv.getType() == ConversationType.chatroom) {
+ mMsg = messages.get(i);
+ } else {
+ mMsg = mConv.getMessage(mMsgIdList.get(i));
+ }
ImageContent ic = (ImageContent) mMsg.getContent();
//每次选择或滑动图片,如果不存在本地图片则下载,显示大图
if (ic.getLocalPath() == null && i != mPosition) {
@@ -478,36 +496,66 @@ private void getImgMsg() {
* 初始化会话中的所有图片路径
*/
private void initImgPathList() {
- mMsgIdList = this.getIntent().getIntegerArrayListExtra(JGApplication.MsgIDs);
- Message msg;
ImageContent ic;
- for (int msgID : mMsgIdList) {
- msg = mConv.getMessage(msgID);
- if (msg.getContentType().equals(ContentType.image)) {
- ic = (ImageContent) msg.getContent();
+ if (mConv.getType() == ConversationType.chatroom) {
+ messages.clear();
+ messages.addAll(Message.fromJsonToCollection(getIntent().getStringExtra(MSG_LIST_JSON)));
+ for (Message message : messages) {
+ ic = (ImageContent) message.getContent();
if (!TextUtils.isEmpty(ic.getLocalPath())) {
mPathList.add(ic.getLocalPath());
} else {
mPathList.add(ic.getLocalThumbnailPath());
}
}
+ } else {
+ Message msg;
+ mMsgIdList = this.getIntent().getIntegerArrayListExtra(JGApplication.MsgIDs);
+ for (int msgID : mMsgIdList) {
+ msg = mConv.getMessage(msgID);
+ if (msg.getContentType().equals(ContentType.image)) {
+ ic = (ImageContent) msg.getContent();
+ if (!TextUtils.isEmpty(ic.getLocalPath())) {
+ mPathList.add(ic.getLocalPath());
+ } else {
+ mPathList.add(ic.getLocalThumbnailPath());
+ }
+ }
+ }
+ }
+ }
+
+ private int getChatRoomMsgItem(Message msg) {
+ int item = 0;
+ for (int i = 0; i < messages.size(); i++) {
+ if (messages.get(i).getServerMessageId().equals(msg.getServerMessageId())) {
+ item = i;
+ break;
+ }
}
+ return item;
}
- private void initCurrentItem() {
+ protected void initCurrentItem() {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Toast.makeText(this, this.getString(R.string.jmui_local_picture_not_found_toast), Toast.LENGTH_SHORT).show();
}
- mMsg = mConv.getMessage(mMessageId);
+ int currentItem = 0;
+ if (mConv.getType() == ConversationType.chatroom) {
+ mMsg = Message.fromJson(getIntent().getStringExtra(MSG_JSON));
+ currentItem = getChatRoomMsgItem(mMsg);
+ } else {
+ mMsg = mConv.getMessage(mMessageId);
+ currentItem = mMsgIdList.indexOf(mMsg.getId());
+ }
photoView = new PhotoView(mFromChatActivity, this);
- int currentItem = mMsgIdList.indexOf(mMsg.getId());
try {
ImageContent ic = (ImageContent) mMsg.getContent();
//如果点击的是第一张图片并且图片未下载过,则显示大图
- if (ic.getLocalPath() == null && mMsgIdList.indexOf(mMsg.getId()) == 0) {
+ if (ic.getLocalPath() == null && currentItem == 0) {
downloadImage();
}
- String path = mPathList.get(mMsgIdList.indexOf(mMsg.getId()));
+ String path = mPathList.get(currentItem);
//如果发送方上传了原图
if (ic.getBooleanExtra("originalPicture") != null && ic.getBooleanExtra("originalPicture")) {
mLoadBtn.setVisibility(View.GONE);
@@ -781,6 +829,7 @@ public void handleMessage(android.os.Message msg) {
if (activity != null) {
switch (msg.what) {
case DOWNLOAD_ORIGIN_IMAGE_SUCCEED:
+ activity.mProgressDialog.dismiss();
//更新图片并显示
Bundle bundle = msg.getData();
activity.mPathList.set(bundle.getInt(JGApplication.POSITION), bundle.getString("path"));
diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java
index 765623ec..5f5aa771 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/ChatActivity.java
@@ -3,6 +3,7 @@
import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
+import android.app.ProgressDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -26,15 +27,26 @@
import com.sj.emoji.EmojiBean;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+import org.json.JSONException;
+import org.json.JSONObject;
+
import java.io.File;
import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
+import cn.jpush.im.android.api.ChatRoomManager;
import cn.jpush.im.android.api.JMessageClient;
import cn.jpush.im.android.api.callback.GetGroupInfoCallback;
+import cn.jpush.im.android.api.callback.GetUserInfoListCallback;
+import cn.jpush.im.android.api.callback.RequestCallback;
import cn.jpush.im.android.api.content.EventNotificationContent;
import cn.jpush.im.android.api.content.FileContent;
import cn.jpush.im.android.api.content.ImageContent;
@@ -43,6 +55,9 @@
import cn.jpush.im.android.api.enums.ContentType;
import cn.jpush.im.android.api.enums.ConversationType;
import cn.jpush.im.android.api.enums.MessageDirect;
+import cn.jpush.im.android.api.event.ChatRoomMessageEvent;
+import cn.jpush.im.android.api.event.ChatRoomNotificationEvent;
+import cn.jpush.im.android.api.event.CommandNotificationEvent;
import cn.jpush.im.android.api.event.MessageEvent;
import cn.jpush.im.android.api.event.MessageReceiptStatusChangeEvent;
import cn.jpush.im.android.api.event.MessageRetractEvent;
@@ -52,7 +67,6 @@
import cn.jpush.im.android.api.model.Message;
import cn.jpush.im.android.api.model.UserInfo;
import cn.jpush.im.android.api.options.MessageSendingOptions;
-import cn.jpush.im.android.eventbus.EventBus;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.adapter.ChattingListAdapter;
@@ -68,6 +82,7 @@
import jiguang.chat.pickerimage.utils.StorageType;
import jiguang.chat.pickerimage.utils.StorageUtil;
import jiguang.chat.pickerimage.utils.StringUtil;
+import jiguang.chat.utils.CommonUtils;
import jiguang.chat.utils.IdHelper;
import jiguang.chat.utils.SharePreferenceManager;
import jiguang.chat.utils.SimpleCommonUtils;
@@ -78,9 +93,9 @@
import jiguang.chat.utils.keyboard.data.EmoticonEntity;
import jiguang.chat.utils.keyboard.interfaces.EmoticonClickListener;
import jiguang.chat.utils.keyboard.utils.EmoticonsKeyboardUtils;
-import jiguang.chat.utils.keyboard.widget.EmoticonsEditText;
import jiguang.chat.utils.keyboard.widget.FuncLayout;
import jiguang.chat.utils.photovideo.takevideo.CameraActivity;
+import jiguang.chat.utils.photovideo.takevideo.utils.LogUtils;
import jiguang.chat.view.ChatView;
import jiguang.chat.view.SimpleAppsGridView;
import jiguang.chat.view.TipItem;
@@ -140,11 +155,15 @@ public class ChatActivity extends BaseActivity implements FuncLayout.OnFuncKeyBo
InputMethodManager mImm;
private final UIHandler mUIHandler = new UIHandler(this);
private boolean mAtAll = false;
+ private boolean isChatRoom = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (!EventBus.getDefault().isRegistered(this)) {
+ EventBus.getDefault().register(this);
+ }
mContext = this;
setContentView(R.layout.activity_chat);
@@ -157,9 +176,90 @@ protected void onCreate(Bundle savedInstanceState) {
ButterKnife.bind(this);
- initData();
initView();
+ //来自聊天室
+ ConversationType conversationType = (ConversationType) getIntent().getSerializableExtra(JGApplication.CONV_TYPE);
+ if (conversationType != null && conversationType == ConversationType.chatroom) {
+ initChatRoom(getIntent().getLongExtra("chatRoomId", 0));
+ mTargetId = String.valueOf(getIntent().getLongExtra("chatRoomId", 0));
+ mChatView.setChatTitle(getIntent().getStringExtra("chatRoomName"));
+ isChatRoom = true;
+ } else {
+ initData();
+ }
+ }
+ @Override
+ public void onDestroy() {
+ EventBus.getDefault().unregister(this);
+ super.onDestroy();
+ }
+
+ private void initChatRoom(long chatRoomId) {
+ ProgressDialog dialog = new ProgressDialog(mContext);
+ dialog.setMessage("正在进入聊天室...");
+ dialog.show();
+ dialog.setOnCancelListener((d) -> {
+ d.dismiss();
+ ChatActivity.this.finish();
+ });
+ ChatRoomManager.enterChatRoom(chatRoomId, new RequestCallback() {
+ @Override
+ public void gotResult(int i, String s, Conversation conversation) {
+ if (i == 0) {
+ dialog.dismiss();
+ if (conversation == null) {
+ mConv = Conversation.createChatRoomConversation(chatRoomId);
+ } else {
+ mConv = conversation;
+ }
+ initChatRoomData();
+ } else if (i == 851003) { // 已经在聊天室中先退出聊天室再进入
+ ChatRoomManager.leaveChatRoom(chatRoomId, new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+ if (i == 0) {
+ ChatRoomManager.enterChatRoom(chatRoomId, new RequestCallback() {
+ @Override
+ public void gotResult(int i, String s, Conversation conversation) {
+ dialog.dismiss();
+ if (i == 0) {
+ if (conversation == null) {
+ mConv = Conversation.createChatRoomConversation(chatRoomId);
+ } else {
+ mConv = conversation;
+ }
+ initChatRoomData();
+ }
+ }
+ });
+ } else if (i == 852004) {
+ dialog.dismiss();
+ mConv = Conversation.createChatRoomConversation(chatRoomId);
+ initChatRoomData();
+ } else {
+ dialog.dismiss();
+ Toast.makeText(ChatActivity.this, "进入聊天室失败" + s, Toast.LENGTH_SHORT).show();
+ finish();
+ }
+ }
+ });
+ } else {
+ dialog.dismiss();
+ Toast.makeText(ChatActivity.this, "进入聊天室失败" + s, Toast.LENGTH_SHORT).show();
+ finish();
+ }
+ }
+ });
+ }
+
+ private void initChatRoomData() {
+ mChatAdapter = new ChattingListAdapter(mContext, mConv, longClickListener);
+ mChatView.setChatListAdapter(mChatAdapter);
+ mChatView.setToBottom();
+ mChatView.setConversation(mConv);
+ mChatView.setGroupIcon();
+ initEmoticonsKeyBoardBar();
}
private void initData() {
@@ -169,6 +269,7 @@ private void initData() {
mTargetAppKey = intent.getStringExtra(TARGET_APP_KEY);
mTitle = intent.getStringExtra(JGApplication.CONV_TITLE);
mMyInfo = JMessageClient.getMyInfo();
+ initEmoticonsKeyBoardBar();
if (!TextUtils.isEmpty(mTargetId)) {
//单聊
mIsSingle = true;
@@ -182,6 +283,7 @@ private void initData() {
//群聊
mIsSingle = false;
mGroupId = intent.getLongExtra(GROUP_ID, 0);
+ mTargetId = String.valueOf(mGroupId);
final boolean fromGroup = intent.getBooleanExtra("fromGroup", false);
if (fromGroup) {
mChatView.setChatTitle(mTitle, intent.getIntExtra(MEMBERS_COUNT, 0));
@@ -257,7 +359,8 @@ public void onDropDown() {
}
private void initView() {
- initEmoticonsKeyBoardBar();
+ lvChat = (DropDownListView) findViewById(R.id.lv_chat);
+ ekBar = (XhsEmoticonsKeyBoard) findViewById(R.id.ek_bar);
initListView();
ekBar.getEtChat().addTextChangedListener(new TextWatcher() {
@@ -288,7 +391,6 @@ public void afterTextChanged(Editable arg0) {
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
-
}
@Override
@@ -301,6 +403,31 @@ public void onTextChanged(CharSequence s, int start, int count, int after) {
}
}
});
+
+ ekBar.getEtChat().setOnFocusChangeListener((v, hasFocus) -> {
+ String content;
+ if (hasFocus) {
+ content = "{\"type\": \"input\",\"content\": {\"message\": \"对方正在输入\"}}";
+ } else {
+ content = "{\"type\": \"input\",\"content\": {\"message\": \"\"}}";
+ }
+ if (mIsSingle) {
+ JMessageClient.sendSingleTransCommand(mTargetId, null, content, new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+
+ }
+ });
+ }
+ });
+
+ mChatView.getChatListView().setOnTouchListener((v, event) -> {
+ mChatView.getChatListView().setFocusable(true);
+ mChatView.getChatListView().setFocusableInTouchMode(true);
+ mChatView.getChatListView().requestFocus();
+ CommonUtils.hideKeyboard(mContext);
+ return false;
+ });
}
private void initEmoticonsKeyBoardBar() {
@@ -309,31 +436,28 @@ private void initEmoticonsKeyBoardBar() {
SimpleAppsGridView gridView = new SimpleAppsGridView(this);
ekBar.addFuncView(gridView);
- ekBar.getEtChat().setOnSizeChangedListener(new EmoticonsEditText.OnSizeChangedListener() {
- @Override
- public void onSizeChanged(int w, int h, int oldw, int oldh) {
- scrollToBottom();
- }
- });
+ ekBar.getEtChat().setOnSizeChangedListener((w, h, oldw, oldh) -> scrollToBottom());
//发送按钮
- ekBar.getBtnSend().setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- String mcgContent = ekBar.getEtChat().getText().toString();
- scrollToBottom();
- if (mcgContent.equals("")) {
- return;
- }
- Message msg;
- TextContent content = new TextContent(mcgContent);
- if (mAtAll) {
- msg = mConv.createSendMessageAtAllMember(content, null);
- mAtAll = false;
- } else if (null != mAtList) {
- msg = mConv.createSendMessage(content, mAtList, null);
- } else {
- msg = mConv.createSendMessage(content);
- }
+ //发送文本消息
+ ekBar.getBtnSend().setOnClickListener(v -> {
+ String mcgContent = ekBar.getEtChat().getText().toString();
+ scrollToBottom();
+ if (mcgContent.equals("")) {
+ return;
+ }
+ Message msg;
+ TextContent content = new TextContent(mcgContent);
+ if (mAtAll) {
+ msg = mConv.createSendMessageAtAllMember(content, null);
+ mAtAll = false;
+ } else if (null != mAtList) {
+ msg = mConv.createSendMessage(content, mAtList, null);
+ } else {
+ LogUtils.d("ChatActivity", "create send message conversation = " + mConv + "==content==" + content.toString());
+ msg = mConv.createSendMessage(content);
+ }
+
+ if (!isChatRoom) {
//设置需要已读回执
MessageSendingOptions options = new MessageSendingOptions();
options.setNeedReadReceipt(true);
@@ -346,6 +470,10 @@ public void onClick(View v) {
if (forDel != null) {
forDel.clear();
}
+ } else {
+ JMessageClient.sendMessage(msg);
+ mChatAdapter.addMsgToList(msg);
+ ekBar.getEtChat().setText("");
}
});
//切换语音输入
@@ -369,7 +497,12 @@ public void onClick(View v) {
returnBtn();
break;
case R.id.jmui_right_btn:
- startChatDetailActivity(mTargetId, mTargetAppKey, mGroupId);
+ //如果是聊天室
+ if (isChatRoom) {
+ startChatRoomActivity(getIntent().getLongExtra("chatRoomId", 0));
+ } else {
+ startChatDetailActivity(mTargetId, mTargetAppKey, mGroupId);
+ }
break;
case R.id.jmui_at_me_btn:
if (mUnreadMsgCnt < ChattingListAdapter.PAGE_MESSAGE_COUNT) {
@@ -384,22 +517,50 @@ public void onClick(View v) {
}
}
+ private void startChatRoomActivity(long chatRoomId) {
+ Intent intent = new Intent(ChatActivity.this, ChatRoomInfoActivity.class);
+ intent.putExtra("chatRoomId", chatRoomId);
+ startActivity(intent);
+ }
+
@Override
public void onBackPressed() {
- super.onBackPressed();
returnBtn();
}
private void returnBtn() {
mConv.resetUnreadCount();
dismissSoftInput();
+ if (mChatAdapter != null) {
+ mChatAdapter.stopMediaPlayer();
+ }
JMessageClient.exitConversation();
//发送保存为草稿事件到会话列表
EventBus.getDefault().post(new Event.Builder().setType(EventType.draft)
.setConversation(mConv)
.setDraft(ekBar.getEtChat().getText().toString())
.build());
- finish();
+ JGApplication.delConversation = null;
+ if (mConv.getAllMessage() == null || mConv.getAllMessage().size() == 0) {
+ if (mIsSingle) {
+ JMessageClient.deleteSingleConversation(mTargetId);
+ } else {
+ JMessageClient.deleteGroupConversation(mGroupId);
+ }
+ JGApplication.delConversation = mConv;
+ }
+ if (isChatRoom) {
+ ChatRoomManager.leaveChatRoom(Long.valueOf(mTargetId), new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+ ChatActivity.this.finish();
+ ChatActivity.super.onBackPressed();
+ }
+ });
+ } else {
+ finish();
+ super.onBackPressed();
+ }
}
private void dismissSoftInput() {
@@ -520,16 +681,18 @@ protected void onPause() {
@Override
protected void onResume() {
String targetId = getIntent().getStringExtra(TARGET_ID);
- if (!mIsSingle) {
+ if (mIsSingle) {
+ if (null != targetId) {
+ String appKey = getIntent().getStringExtra(TARGET_APP_KEY);
+ JMessageClient.enterSingleConversation(targetId, appKey);
+ }
+ } else if (!isChatRoom) {
long groupId = getIntent().getLongExtra(GROUP_ID, 0);
if (groupId != 0) {
JGApplication.isAtMe.put(groupId, false);
JGApplication.isAtall.put(groupId, false);
JMessageClient.enterGroupConversation(groupId);
}
- } else if (null != targetId) {
- String appKey = getIntent().getStringExtra(TARGET_APP_KEY);
- JMessageClient.enterSingleConversation(targetId, appKey);
}
//历史消息中删除后返回到聊天界面刷新界面
@@ -538,16 +701,90 @@ protected void onResume() {
mChatAdapter.removeMessage(msg);
}
}
- mChatAdapter.notifyDataSetChanged();
+ if (mChatAdapter != null)
+ mChatAdapter.notifyDataSetChanged();
//发送名片返回聊天界面刷新信息
if (SharePreferenceManager.getIsOpen()) {
- initData();
+ if (!isChatRoom) {
+ initData();
+ }
SharePreferenceManager.setIsOpen(false);
}
super.onResume();
}
+ public void onEvent(CommandNotificationEvent event) {
+ if (event.getType().equals(CommandNotificationEvent.Type.single)) {
+ String msg = event.getMsg();
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ JSONObject object = new JSONObject(msg);
+ JSONObject jsonContent = object.getJSONObject("content");
+ String messageString = jsonContent.getString("message");
+ if (TextUtils.isEmpty(messageString)) {
+ mChatView.setTitle(mConv.getTitle());
+ } else {
+ mChatView.setTitle(messageString);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+ }
+
+ public void onEventMainThread(ChatRoomMessageEvent event) {
+ List messages = event.getMessages();
+ mChatAdapter.addMsgListToList(messages);
+ }
+
+ public void onEventMainThread(ChatRoomNotificationEvent event) {
+ try {
+ Constructor constructor = EventNotificationContent.class.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ List messages = new ArrayList<>();
+ switch (event.getType()) {
+ case add_chatroom_admin:
+ case del_chatroom_admin:
+ event.getTargetUserInfoList(new GetUserInfoListCallback() {
+ @Override
+ public void gotResult(int i, String s, List list) {
+ if (i == 0) {
+ for (UserInfo userInfo : list) {
+ try {
+ EventNotificationContent content = (EventNotificationContent) constructor.newInstance();
+ Field field = content.getClass().getSuperclass().getDeclaredField("contentType");
+ field.setAccessible(true);
+ field.set(content, ContentType.eventNotification);
+ String user = userInfo.getUserID() == JMessageClient.getMyInfo().getUserID()
+ ? "你" : TextUtils.isEmpty(userInfo.getNickname()) ? userInfo.getUserName() : userInfo.getNickname();
+ String result = event.getType() == ChatRoomNotificationEvent.Type.add_chatroom_admin ? "被设置成管理员" : "被取消管理员";
+ content.setStringExtra("msg", user + result);
+ if (mConv != null) {
+ messages.add(mConv.createSendMessage(content));
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ if (messages.size() > 0) {
+ mChatAdapter.addMsgListToList(messages);
+ }
+ }
+ }
+ });
+ break;
+ default:
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
public void onEvent(MessageEvent event) {
final Message message = event.getMessage();
@@ -565,20 +802,16 @@ public void onEvent(MessageEvent event) {
//群主把当前用户添加到群聊,则显示聊天详情按钮
refreshGroupNum();
if (userNames.contains(mMyInfo.getNickname()) || userNames.contains(mMyInfo.getUserName())) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mChatView.showRightBtn();
- }
- });
+ runOnUiThread(() -> mChatView.showRightBtn());
}
break;
case group_member_removed:
//删除群成员事件
userNames = ((EventNotificationContent) message.getContent()).getUserNames();
+ UserInfo operator = ((EventNotificationContent) message.getContent()).getOperatorUserInfo();
//群主删除了当前用户,则隐藏聊天详情按钮
- if (userNames.contains(mMyInfo.getNickname()) || userNames.contains(mMyInfo.getUserName())) {
+ if ((userNames.contains(mMyInfo.getNickname()) || userNames.contains(mMyInfo.getUserName())) && operator.getUserID() != mMyInfo.getUserID()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
@@ -696,6 +929,9 @@ private void refreshGroupNum() {
@Override
public void onContentLongClick(final int position, View view) {
+ if (isChatRoom) {
+ return;
+ }
final Message msg = mChatAdapter.getMessage(position);
if (msg == null) {
@@ -915,6 +1151,7 @@ public void onEventMainThread(MessageReceiptStatusChangeEvent event) {
}
}
+ @Subscribe (threadMode = ThreadMode.MAIN)
public void onEventMainThread(ImageEvent event) {
Intent intent;
switch (event.getFlag()) {
@@ -946,9 +1183,9 @@ public void onEventMainThread(ImageEvent event) {
Toast.makeText(this, "请在应用管理中打开“位置”访问权限!", Toast.LENGTH_LONG).show();
} else {
intent = new Intent(mContext, MapPickerActivity.class);
+ intent.putExtra(JGApplication.CONV_TYPE, mConv.getType());
intent.putExtra(JGApplication.TARGET_ID, mTargetId);
intent.putExtra(JGApplication.TARGET_APP_KEY, mTargetAppKey);
- intent.putExtra(JGApplication.GROUP_ID, mGroupId);
intent.putExtra("sendLocation", true);
startActivityForResult(intent, JGApplication.REQUEST_CODE_SEND_LOCATION);
}
@@ -963,16 +1200,16 @@ public void onEventMainThread(ImageEvent event) {
intent = new Intent(mContext, SendFileActivity.class);
intent.putExtra(JGApplication.TARGET_ID, mTargetId);
intent.putExtra(JGApplication.TARGET_APP_KEY, mTargetAppKey);
- intent.putExtra(JGApplication.GROUP_ID, mGroupId);
+ intent.putExtra(JGApplication.CONV_TYPE, mConv.getType());
startActivityForResult(intent, JGApplication.REQUEST_CODE_SEND_FILE);
}
break;
case JGApplication.BUSINESS_CARD:
intent = new Intent(mContext, FriendListActivity.class);
- intent.putExtra("isSingle", mIsSingle);
- intent.putExtra("userId", mTargetId);
- intent.putExtra("groupId", mGroupId);
- startActivity(intent);
+ intent.putExtra(JGApplication.CONV_TYPE, mConv.getType());
+ intent.putExtra(JGApplication.TARGET_ID, mTargetId);
+ intent.putExtra(JGApplication.TARGET_APP_KEY, mTargetAppKey);;
+ startActivityForResult(intent, JGApplication.REQUEST_CODE_FRIEND_LIST);
break;
case JGApplication.TACK_VIDEO:
case JGApplication.TACK_VOICE:
@@ -995,6 +1232,20 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
case RequestCode.PICK_IMAGE://4
onPickImageActivityResult(requestCode, data);
break;
+ case JGApplication.REQUEST_CODE_FRIEND_LIST:
+ // 发送名片成功后,聊天室需要添加消息
+ if (resultCode == RESULT_OK && isChatRoom) {
+ String msgJson = data.getStringExtra(JGApplication.MSG_JSON);
+ if (msgJson != null) {
+ Message msg = Message.fromJson(msgJson);
+ if (msg != null) {
+ mChatAdapter.addMsgToList(msg);
+ mChatAdapter.notifyDataSetChanged();
+ }
+ }
+ }
+ break;
+
}
switch (resultCode) {
@@ -1030,7 +1281,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
public void gotResult(int responseCode, String responseMessage, ImageContent imageContent) {
if (responseCode == 0) {
Message msg = mConv.createSendMessage(imageContent);
- handleSendMsg(msg.getId());
+ handleSendMsg(msg);
}
}
});
@@ -1043,7 +1294,7 @@ public void gotResult(int responseCode, String responseMessage, ImageContent ima
FileContent fileContent = new FileContent(new File(path));
fileContent.setStringExtra("video", "mp4");
Message msg = mConv.createSendMessage(fileContent);
- handleSendMsg(msg.getId());
+ handleSendMsg(msg);
} catch (Exception e) {
e.printStackTrace();
}
@@ -1075,9 +1326,11 @@ public void gotResult(int responseCode, String responseMessage, ImageContent ima
mChatView.setToBottom();
break;
case JGApplication.RESULT_CODE_SEND_FILE:
- int[] intArrayExtra = data.getIntArrayExtra(MsgIDs);
- for (int msgId : intArrayExtra) {
- handleSendMsg(msgId);
+ String msgListJson = data.getStringExtra(JGApplication.MSG_LIST_JSON);
+ if (msgListJson != null) {
+ for (Message msg : Message.fromJsonToCollection(msgListJson)) {
+ handleSendMsg(msg);
+ }
}
break;
case JGApplication.RESULT_CODE_CHAT_DETAIL:
@@ -1141,7 +1394,7 @@ public void sendImage(final File file, boolean isOrig) {
public void gotResult(int responseCode, String responseMessage, ImageContent imageContent) {
if (responseCode == 0) {
Message msg = mConv.createSendMessage(imageContent);
- handleSendMsg(msg.getId());
+ handleSendMsg(msg);
}
}
});
@@ -1160,7 +1413,7 @@ public void gotResult(int responseCode, String responseMessage, ImageContent ima
if (responseCode == 0) {
imageContent.setStringExtra("jiguang", "xiong");
Message msg = mConv.createSendMessage(imageContent);
- handleSendMsg(msg.getId());
+ handleSendMsg(msg);
} else {
ToastUtil.shortToast(mContext, responseMessage);
}
@@ -1171,10 +1424,10 @@ public void gotResult(int responseCode, String responseMessage, ImageContent ima
/**
* 处理发送图片,刷新界面
*
- * @param data intent
+ * @param msg
*/
- private void handleSendMsg(int data) {
- mChatAdapter.setSendMsgs(data);
+ private void handleSendMsg(Message msg) {
+ mChatAdapter.setSendMsgs(msg);
mChatView.setToBottom();
}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChatDetailActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChatDetailActivity.java
index 050e17ac..3ca35bd5 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/ChatDetailActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/ChatDetailActivity.java
@@ -47,13 +47,14 @@ public class ChatDetailActivity extends BaseActivity {
private static final int ADD_FRIEND_REQUEST_CODE = 3;
public static final int GROUP_DESC = 70;
- public static final int FLAGS_GROUP_DESC = 71;
public static final String GROUP_DESC_KEY = "group_desc_key";
public static final int GROUP_NAME = 72;
- public static final int FLAGS_GROUP_NAME = 73;
public static final String GROUP_NAME_KEY = "group_name_key";
+ private static final int GROUP_DESC_COUNT = 250;
+ private static final int GROUP_NAME_COUNT = 64;
+
private long groupID;
@@ -104,13 +105,15 @@ public void updateGroupNameDesc(long groupId, int nameOrDesc) {
this.groupID = groupId;
Intent intent = new Intent(ChatDetailActivity.this, NickSignActivity.class);
if (nameOrDesc == 1) {
- intent.setFlags(FLAGS_GROUP_NAME);
- intent.putExtra("group_name", mGroupName);
+ intent.putExtra(NickSignActivity.TYPE, NickSignActivity.Type.GROUP_NAME);
+ intent.putExtra(NickSignActivity.COUNT, GROUP_NAME_COUNT);
+ intent.putExtra(NickSignActivity.DESC, mGroupName);
} else {
- intent.setFlags(FLAGS_GROUP_DESC);
- intent.putExtra("group_desc", mGroupDesc);
+ intent.putExtra(NickSignActivity.TYPE, NickSignActivity.Type.GROUP_DESC);
+ intent.putExtra(NickSignActivity.COUNT, GROUP_DESC_COUNT);
+ intent.putExtra(NickSignActivity.DESC, mGroupDesc);
}
- startActivityForResult(intent, GROUP_NAME);
+ startActivityForResult(intent, nameOrDesc == 1 ? GROUP_NAME : GROUP_DESC);
}
@Override
diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChatRoomDetailActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChatRoomDetailActivity.java
new file mode 100644
index 00000000..53c85bf6
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/ChatRoomDetailActivity.java
@@ -0,0 +1,78 @@
+package jiguang.chat.activity;
+
+import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.Button;
+import android.widget.TextView;
+
+import java.util.Collections;
+import java.util.List;
+
+import cn.jpush.im.android.api.ChatRoomManager;
+import cn.jpush.im.android.api.callback.RequestCallback;
+import cn.jpush.im.android.api.enums.ConversationType;
+import cn.jpush.im.android.api.model.ChatRoomInfo;
+import jiguang.chat.R;
+import jiguang.chat.application.JGApplication;
+import jiguang.chat.utils.dialog.LoadDialog;
+
+/**
+ * Created by ${chenyn} on 2017/10/31.
+ */
+
+@SuppressLint("Registered")
+public class ChatRoomDetailActivity extends BaseActivity {
+
+ private TextView mChatRoomName;
+ private TextView mChatRoomID;
+ private TextView mChatRoomMember;
+ private TextView mChatRoomDesc;
+ private Button mEnterChatRoom;
+ private ChatRoomInfo mInfo;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_chat_room_detail);
+ initView();
+ initData();
+ }
+
+ private void initData() {
+ LoadDialog.show(ChatRoomDetailActivity.this, "正在加载...");
+ long chatRoomId = getIntent().getLongExtra("chatRoomId", 0);
+ ChatRoomManager.getChatRoomInfos(Collections.singleton(chatRoomId), new RequestCallback>() {
+ @Override
+ public void gotResult(int i, String s, List chatRoomInfos) {
+ LoadDialog.dismiss(ChatRoomDetailActivity.this);
+ if (i == 0) {
+ mInfo = chatRoomInfos.get(0);
+ mChatRoomName.setText(mInfo.getName());
+ mChatRoomID.setText(mInfo.getRoomID() + "");
+ mChatRoomDesc.setText(mInfo.getDescription());
+ mChatRoomMember.setText(mInfo.getTotalMemberCount() + "");
+ }
+ }
+ });
+ mEnterChatRoom.setOnClickListener(v -> {
+ Intent intent = new Intent(ChatRoomDetailActivity.this, ChatActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ intent.putExtra(JGApplication.CONV_TYPE, ConversationType.chatroom);
+ intent.putExtra("chatRoomId", chatRoomId);
+ intent.putExtra("chatRoomName", mInfo.getName());
+ startActivity(intent);
+ });
+ }
+
+ private void initView() {
+ initTitle(true, true, "详细资料", "", false, "");
+ mChatRoomName = (TextView) findViewById(R.id.tv_chatRoomName);
+ mChatRoomID = (TextView) findViewById(R.id.tv_chatRoomID);
+ mChatRoomMember = (TextView) findViewById(R.id.tv_chatRoomMember);
+ mChatRoomDesc = (TextView) findViewById(R.id.tv_chatRoomDesc);
+ mEnterChatRoom = (Button) findViewById(R.id.btn_enterChatRoom);
+
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChatRoomInfoActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChatRoomInfoActivity.java
new file mode 100644
index 00000000..50647b9d
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/ChatRoomInfoActivity.java
@@ -0,0 +1,222 @@
+package jiguang.chat.activity;
+
+import android.app.Dialog;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import cn.jpush.im.android.api.ChatRoomManager;
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetUserInfoCallback;
+import cn.jpush.im.android.api.callback.RequestCallback;
+import cn.jpush.im.android.api.event.ChatRoomNotificationEvent;
+import cn.jpush.im.android.api.model.ChatRoomInfo;
+import cn.jpush.im.android.api.model.UserInfo;
+import cn.jpush.im.api.BasicCallback;
+import jiguang.chat.R;
+import jiguang.chat.adapter.ChatRoomKeeperGridAdapter;
+import jiguang.chat.application.JGApplication;
+import jiguang.chat.utils.DialogCreator;
+import jiguang.chat.utils.ToastUtil;
+import jiguang.chat.view.NoScrollGridView;
+
+/**
+ * Created by ${chenyn} on 2017/11/8.
+ */
+
+public class ChatRoomInfoActivity extends BaseActivity implements View.OnClickListener {
+
+ private TextView mTvChatRoomName, mTvChatRoomDesc, mTvChatRoomOwner;
+ private NoScrollGridView mGvChatRoomKeeper;
+ private ChatRoomKeeperGridAdapter mGridAdapter;
+ private List keeperList = new ArrayList<>();
+ private List keeperListDisplay = new ArrayList<>();
+ private ChatRoomInfo mChatRoomInfo;
+ private UserInfo ownerInfo;
+ private long roomId;
+ private boolean isOwner;
+ private Dialog exitDialog;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_chat_room_info);
+ initTitle(true, true, "聊天室资料", "", false, "");
+ initData();
+ }
+
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent();
+ switch (v.getId()) {
+ case R.id.ll_chat_room_name:
+ intent.setClass(ChatRoomInfoActivity.this, NickSignActivity.class);
+ intent.putExtra(NickSignActivity.TYPE, NickSignActivity.Type.CHAT_ROOM_NAME);
+ intent.putExtra(NickSignActivity.DESC, mChatRoomInfo != null ? mChatRoomInfo.getName() : "");
+ startActivity(intent);
+ break;
+ case R.id.ll_chat_room_desc:
+ intent.setClass(ChatRoomInfoActivity.this, NickSignActivity.class);
+ intent.putExtra(NickSignActivity.TYPE, NickSignActivity.Type.CHAT_ROOM_DESC);
+ intent.putExtra(NickSignActivity.DESC, mChatRoomInfo != null ? mChatRoomInfo.getDescription() : "");
+ startActivity(intent);
+ break;
+ case R.id.ll_chat_room_keeper:
+ intent.setClass(ChatRoomInfoActivity.this, ChatRoomKeeperActivity.class);
+ intent.putExtra(JGApplication.ROOM_ID, roomId);
+ intent.putExtra(ChatRoomKeeperActivity.IS_OWNER, isOwner);
+ startActivity(intent);
+ break;
+ case R.id.ll_chat_room_owner:
+ if (isOwner) {
+ intent.setClass(ChatRoomInfoActivity.this, PersonalActivity.class);
+ } else {
+ intent.setClass(ChatRoomInfoActivity.this, GroupUserInfoActivity.class);
+ intent.putExtra(GroupUserInfoActivity.IS_FROM_GROUP, false);
+ intent.putExtra(JGApplication.NAME, ownerInfo != null ? ownerInfo.getUserName() : "");
+ intent.putExtra(JGApplication.TARGET_APP_KEY, ownerInfo != null ? ownerInfo.getAppKey() : "");
+ }
+ startActivity(intent);
+ break;
+ case R.id.btn_exit_room:
+ View.OnClickListener listener = (v1) -> {
+ switch (v1.getId()) {
+ case R.id.jmui_cancel_btn:
+ exitDialog.cancel();
+ break;
+ case R.id.jmui_commit_btn:
+ exitChatRoom();
+ exitDialog.cancel();
+ break;
+ }
+ };
+ exitDialog = DialogCreator.createBaseDialogWithTitle(ChatRoomInfoActivity.this, "确定退出聊天室", listener);
+ exitDialog.show();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void exitChatRoom() {
+ Dialog loadingDialog = DialogCreator.createLoadingDialog(ChatRoomInfoActivity.this,
+ "正在处理");
+ loadingDialog.show();
+ ChatRoomManager.leaveChatRoom(roomId, new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+ loadingDialog.dismiss();
+ if (i == 0) {
+ Intent intent = new Intent();
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ intent.setClass(ChatRoomInfoActivity.this, MainActivity.class);
+ startActivity(intent);
+ } else {
+ ToastUtil.shortToast(ChatRoomInfoActivity.this, "退出失败");
+ }
+ }
+ });
+ }
+
+ private void initData() {
+ mTvChatRoomName = (TextView) findViewById(R.id.tv_chatRoomName);
+ mTvChatRoomDesc = (TextView) findViewById(R.id.tv_chatRoomDesc);
+ mTvChatRoomOwner = (TextView) findViewById(R.id.tv_chatRoomOwner);
+ mGvChatRoomKeeper = (NoScrollGridView) findViewById(R.id.grid_chatRommKeeper);
+ mGvChatRoomKeeper.setClickable(false);
+ mGvChatRoomKeeper.setPressed(false);
+ mGvChatRoomKeeper.setEnabled(false);
+ roomId = getIntent().getLongExtra("chatRoomId", 0);
+ findViewById(R.id.ll_chat_room_name).setOnClickListener(this);
+ findViewById(R.id.ll_chat_room_desc).setOnClickListener(this);
+ findViewById(R.id.ll_chat_room_keeper).setOnClickListener(this);
+ findViewById(R.id.ll_chat_room_owner).setOnClickListener(this);
+ findViewById(R.id.btn_exit_room).setOnClickListener(this);
+ Dialog loadingDialog = DialogCreator.createLoadingDialog(this, "正在加载...");
+ loadingDialog.show();
+ AtomicInteger taskCount = new AtomicInteger(2);
+ ChatRoomManager.getChatRoomInfos(Collections.singleton(roomId), new RequestCallback>() {
+ @Override
+ public void gotResult(int i, String s, List chatRoomInfos) {
+ if (i == 0) {
+ mChatRoomInfo = chatRoomInfos.get(0);
+ mTvChatRoomName.setText(mChatRoomInfo.getName());
+ mTvChatRoomDesc.setText(mChatRoomInfo.getDescription());
+ mChatRoomInfo.getOwnerInfo(new GetUserInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, UserInfo userInfo) {
+ if (i == 0) {
+ ownerInfo = userInfo;
+ isOwner = (ownerInfo.getUserID() == JMessageClient.getMyInfo().getUserID());
+ mTvChatRoomOwner.setText(ownerInfo.getDisplayName());
+ }
+ if (taskCount.decrementAndGet() == 0) {
+ loadingDialog.dismiss();
+ }
+ }
+ });
+ } else {
+ if (taskCount.decrementAndGet() == 0) {
+ loadingDialog.dismiss();
+ }
+ }
+ }
+ });
+ ChatRoomManager.getChatRoomAdminList(roomId, new RequestCallback>() {
+ @Override
+ public void gotResult(int i, String s, List userInfos) {
+ if (i == 0) {
+ keeperList.clear();
+ keeperListDisplay.clear();
+ keeperList.addAll(userInfos);
+ if (keeperList.size() > 5) {
+ keeperListDisplay.addAll(userInfos.subList(0, 5)); // 只取5个
+ } else {
+ keeperListDisplay.addAll(userInfos);
+ }
+ }
+ mGvChatRoomKeeper.setNumColumns(keeperListDisplay.size());
+ mGridAdapter = new ChatRoomKeeperGridAdapter(ChatRoomInfoActivity.this, keeperListDisplay);
+ mGvChatRoomKeeper.setAdapter(mGridAdapter);
+ if (taskCount.decrementAndGet() == 0) {
+ loadingDialog.dismiss();
+ }
+ }
+ });
+ }
+
+ public void onEvent(ChatRoomNotificationEvent event) {
+ switch (event.getType()) {
+ case del_chatroom_admin:
+ case add_chatroom_admin:
+ ChatRoomManager.getChatRoomAdminList(roomId, new RequestCallback>() {
+ @Override
+ public void gotResult(int i, String s, List userInfos) {
+ if (i == 0) {
+ keeperList.clear();
+ keeperListDisplay.clear();
+ keeperList.addAll(userInfos);
+ if (keeperList.size() > 5) {
+ keeperListDisplay.addAll(userInfos.subList(0, 5)); // 只取5个
+ } else {
+ keeperListDisplay.addAll(userInfos);
+ }
+ }
+ mGvChatRoomKeeper.setNumColumns(keeperListDisplay.size());
+ mGridAdapter.notifyDataSetChanged();
+ }
+ });
+ break;
+ default:
+ break;
+
+ }
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChatRoomKeeperActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChatRoomKeeperActivity.java
new file mode 100644
index 00000000..5fda44c2
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/ChatRoomKeeperActivity.java
@@ -0,0 +1,265 @@
+package jiguang.chat.activity;
+
+import android.app.Dialog;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.text.Editable;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.text.style.ForegroundColorSpan;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+import cn.jpush.im.android.api.ChatRoomManager;
+import cn.jpush.im.android.api.callback.RequestCallback;
+import cn.jpush.im.android.api.event.ChatRoomNotificationEvent;
+import cn.jpush.im.android.api.model.UserInfo;
+import jiguang.chat.R;
+import jiguang.chat.adapter.ChatRoomKeeperListAdapter;
+import jiguang.chat.application.JGApplication;
+import jiguang.chat.utils.DialogCreator;
+import jiguang.chat.utils.HandleResponseCode;
+import jiguang.chat.utils.pinyin.HanyuPinyin;
+
+public class ChatRoomKeeperActivity extends BaseActivity {
+ private TextView mTvNullKeeper;
+ private ListView mLvKeeper;
+ private EditText mEtSearch;
+ private List mKeepers = new ArrayList<>();
+ private List mShowKeeperList = new ArrayList<>();
+ private List mPinyinList = new ArrayList();
+ private ChatRoomKeeperListAdapter mAdapter;
+ private String mSearchText;
+ private MyHandler myHandler;
+ private static final int SEARCH_KEEPER = 0;
+ private static final int SEARCH_MEMBER_SUCCESS = 1;
+ private long roomID;
+ public static final String IS_OWNER = "isOwner";
+ private boolean isOwner;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_chat_room_keeper);
+ initData();
+ }
+
+ private void initData() {
+ initTitle(true, true, "管理员", "", true, "添加");
+ roomID = getIntent().getLongExtra(JGApplication.ROOM_ID, 0);
+ isOwner = getIntent().getBooleanExtra(IS_OWNER, false);
+ if (!isOwner) {
+ mJmui_commit_btn.setVisibility(View.GONE);
+ }
+ mJmui_commit_btn.setOnClickListener((v) -> {
+ Intent intent = new Intent(ChatRoomKeeperActivity.this, SearchForChatRoomActivity.class);
+ intent.putExtra(JGApplication.ROOM_ID, roomID);
+ startActivity(intent);
+ });
+ mTvNullKeeper = (TextView) findViewById(R.id.null_chatRoomKeeper);
+ mLvKeeper = (ListView) findViewById(R.id.lv_chatRoomKeeper);
+ mEtSearch = (EditText) findViewById(R.id.search_et);
+ mEtSearch.addTextChangedListener(watcher);
+ myHandler = new MyHandler(getMainLooper(), this);
+ Dialog loadingDialog = DialogCreator.createLoadingDialog(this, "正在加载...");
+ loadingDialog.show();
+ ChatRoomManager.getChatRoomAdminList(roomID, new RequestCallback>() {
+ @Override
+ public void gotResult(int i, String s, List userInfos) {
+ if (i == 0) {
+ if (userInfos.size() > 0) {
+ mKeepers.clear();
+ mKeepers.addAll(userInfos);
+ addAll(false);
+ } else {
+ mTvNullKeeper.setVisibility(View.VISIBLE);
+ }
+ mAdapter = new ChatRoomKeeperListAdapter(ChatRoomKeeperActivity.this, mShowKeeperList, roomID, isOwner);
+ mLvKeeper.setAdapter(mAdapter);
+ mLvKeeper.setOnItemClickListener(mAdapter);
+ loadingDialog.dismiss();
+ } else {
+ loadingDialog.dismiss();
+ HandleResponseCode.onHandle(ChatRoomKeeperActivity.this, i, false);
+ }
+ }
+ });
+
+ }
+
+ TextWatcher watcher = new TextWatcher() {
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ mSearchText = s.toString().trim();
+ myHandler.removeMessages(SEARCH_KEEPER);
+ myHandler.sendMessageDelayed(myHandler.obtainMessage(SEARCH_KEEPER), 200);
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+
+ }
+ };
+
+ public class ItemModel {
+ public UserInfo data;
+ public SpannableString highlight;
+ public int sortIndex;
+ }
+
+ public void onEventMainThread(ChatRoomNotificationEvent event) {
+ switch (event.getType()) {
+ case add_chatroom_admin:
+ case del_chatroom_admin:
+ if (mAdapter != null) {
+ ChatRoomManager.getChatRoomAdminList(roomID, new RequestCallback>() {
+ @Override
+ public void gotResult(int i, String s, List userInfos) {
+ if (i == 0) {
+ mKeepers.clear();
+ mKeepers.addAll(userInfos);
+ addAll(true);
+ mTvNullKeeper.setVisibility(userInfos.size() > 0 ? View.GONE : View.VISIBLE);
+ }
+ }
+ });
+ }
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ private class MyHandler extends Handler {
+ private final WeakReference mActivity;
+ public MyHandler(Looper looper, ChatRoomKeeperActivity mActivity) {
+ super(looper);
+ this.mActivity = new WeakReference<>(mActivity);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ switch (msg.what) {
+ case SEARCH_KEEPER:
+ if (mShowKeeperList != null) {
+ mShowKeeperList.clear();
+ }
+ filterData();
+ break;
+ case SEARCH_MEMBER_SUCCESS:
+ ChatRoomKeeperActivity activity = mActivity.get();
+ if (activity != null && activity.mAdapter != null) {
+ activity.mAdapter.notifyDataSetChanged();
+ }
+ break;
+ default:
+ break;
+
+ }
+ }
+ }
+
+
+ /**
+ * 根据输入框输入的字符过滤群成员
+ */
+ private void filterData() {
+ if (TextUtils.isEmpty(mSearchText)) {
+ addAll(true);
+ } else {
+ String displayName, pinyin;
+ int sort;
+ SpannableString result;
+ ItemModel model;
+ UserInfo userInfo;
+ for (int i = 0; i < mPinyinList.size(); i++) {
+ sort = 0;
+ userInfo = mKeepers.get(i);
+ displayName = userInfo.getDisplayName();
+ result = new SpannableString(displayName);
+ //先进行拼音匹配
+ pinyin = mPinyinList.get(i).toLowerCase();
+ int offset = pinyin.indexOf(mSearchText.toLowerCase());
+ if (offset != -1) {
+ model = new ItemModel();
+ sort += mSearchText.length();
+ result.setSpan(new ForegroundColorSpan(Color.RED), offset,
+ offset + mSearchText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ //进行直接匹配
+ int index = displayName.indexOf(mSearchText);
+ if (index != -1) {
+ sort += mSearchText.length();
+ result.setSpan(new ForegroundColorSpan(Color.RED), index,
+ index + mSearchText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ model.data = userInfo;
+ model.highlight = result;
+ model.sortIndex = sort;
+ mShowKeeperList.add(model);
+ continue;
+ }
+ model.data = userInfo;
+ model.highlight = result;
+ model.sortIndex = sort;
+ mShowKeeperList.add(model);
+ //进行直接匹配
+ } else {
+ int index = displayName.indexOf(mSearchText);
+ if (index != -1) {
+ sort += mSearchText.length();
+ result.setSpan(new ForegroundColorSpan(Color.RED), index,
+ index + mSearchText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+ model = new ItemModel();
+ model.data = userInfo;
+ model.highlight = result;
+ model.sortIndex = sort;
+ mShowKeeperList.add(model);
+ }
+ }
+ }
+ }
+
+ myHandler.sendEmptyMessage(SEARCH_MEMBER_SUCCESS);
+ }
+
+ private void addAll(boolean needSendMessage) {
+ String nickname, pinyin;
+ ItemModel itemModel;
+ mPinyinList.clear();
+ mShowKeeperList.clear();
+ for (UserInfo userInfo: mKeepers) {
+ itemModel = new ItemModel();
+ itemModel.data = userInfo;
+ nickname = userInfo.getNickname();
+ if (TextUtils.isEmpty(nickname)) {
+ nickname = userInfo.getUserName();
+ }
+ pinyin = HanyuPinyin.getInstance().getStringPinYin(nickname);
+ mPinyinList.add(pinyin);
+ itemModel.highlight = new SpannableString(nickname);
+ mShowKeeperList.add(itemModel);
+ }
+ if (needSendMessage) {
+ myHandler.sendEmptyMessage(SEARCH_MEMBER_SUCCESS);
+ }
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/ChooseAtMemberActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ChooseAtMemberActivity.java
index 87d00104..2088bc6f 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/ChooseAtMemberActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/ChooseAtMemberActivity.java
@@ -23,7 +23,7 @@
import jiguang.chat.utils.keyboard.widget.EmoticonsEditText;
import jiguang.chat.utils.pinyin.UserComparator;
import jiguang.chat.utils.sidebar.SideBar;
-import jiguang.chat.view.listview.StickyListHeadersListView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
/**
diff --git a/chatapp/src/main/java/jiguang/chat/activity/CreateGroupActivity.java b/chatapp/src/main/java/jiguang/chat/activity/CreateGroupActivity.java
index 9f2026c3..ede79a78 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/CreateGroupActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/CreateGroupActivity.java
@@ -1,6 +1,5 @@
package jiguang.chat.activity;
-import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -20,26 +19,18 @@
import java.util.List;
import cn.jpush.im.android.api.JMessageClient;
-import cn.jpush.im.android.api.callback.CreateGroupCallback;
import cn.jpush.im.android.api.callback.GetUserInfoCallback;
-import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.UserInfo;
-import cn.jpush.im.android.eventbus.EventBus;
-import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.adapter.CreateGroupAdapter;
import jiguang.chat.adapter.StickyListAdapter;
import jiguang.chat.application.JGApplication;
import jiguang.chat.database.FriendEntry;
import jiguang.chat.database.UserEntry;
-import jiguang.chat.entity.Event;
-import jiguang.chat.entity.EventType;
-import jiguang.chat.utils.DialogCreator;
-import jiguang.chat.utils.ToastUtil;
import jiguang.chat.utils.keyboard.utils.EmoticonsKeyboardUtils;
import jiguang.chat.utils.pinyin.PinyinComparator;
import jiguang.chat.utils.sidebar.SideBar;
-import jiguang.chat.view.listview.StickyListHeadersListView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
/**
@@ -60,7 +51,6 @@ public class CreateGroupActivity extends BaseActivity implements View.OnClickLis
private GridView imageSelectedGridView;
private CreateGroupAdapter mGroupAdapter;
private Context mContext;
- private Dialog mLoadingDialog;
private FriendEntry mFriendEntry;
private TextView mTv_noFriend;
private TextView mTv_noFilter;
@@ -143,66 +133,16 @@ public void onClick(View v) {
break;
case R.id.finish_btn:
//拿到所选择的userName
- final ArrayList selectedUser = mAdapter.getSelectedUser();
- mLoadingDialog = DialogCreator.createLoadingDialog(mContext,
- mContext.getString(R.string.creating_hint));
- mLoadingDialog.show();
- JMessageClient.createGroup("", "", new CreateGroupCallback() {
- @Override
- public void gotResult(int responseCode, String responseMsg, final long groupId) {
- if (responseCode == 0) {
- if (selectedUser.size() > 0) {
- JMessageClient.addGroupMembers(groupId, selectedUser, new BasicCallback() {
- @Override
- public void gotResult(int responseCode, String responseMessage) {
- mLoadingDialog.dismiss();
- if (responseCode == 0) {
- //如果创建群组时添加了人,那么就在size基础上加上自己
- createGroup(groupId, selectedUser.size() + 1);
- } else if (responseCode == 810007) {
- ToastUtil.shortToast(mContext, "不能添加自己");
- } else {
- ToastUtil.shortToast(mContext, "添加失败");
- }
- }
- });
- } else {
- mLoadingDialog.dismiss();
- //如果创建群组时候没有选择人,那么size就是1
- createGroup(groupId, 1);
- }
- } else {
- mLoadingDialog.dismiss();
- ToastUtil.shortToast(mContext, responseMsg);
- }
- }
- });
+ if (JGApplication.selectedUser != null && JGApplication.selectedUser.size() > 0) {
+ JGApplication.selectedUser.clear();
+ }
+ JGApplication.selectedUser = mAdapter.getSelectedUser();
+ Intent intent = new Intent(mContext, SelectCreateGroupTypeActivity.class);
+ startActivity(intent);
break;
}
}
- private void createGroup(long groupId, int groupMembersSize) {
- Conversation groupConversation = JMessageClient.getGroupConversation(groupId);
- if (groupConversation == null) {
- groupConversation = Conversation.createGroupConversation(groupId);
- EventBus.getDefault().post(new Event.Builder()
- .setType(EventType.createConversation)
- .setConversation(groupConversation)
- .build());
- }
-
- Intent intent = new Intent();
- //设置跳转标志
- intent.putExtra("fromGroup", true);
- intent.putExtra(JGApplication.CONV_TITLE, groupConversation.getTitle());
- intent.putExtra(JGApplication.MEMBERS_COUNT, groupMembersSize);
- intent.putExtra(JGApplication.GROUP_ID, groupId);
- intent.setClass(mContext, ChatActivity.class);
- mContext.startActivity(intent);
- finish();
- }
-
-
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
diff --git a/chatapp/src/main/java/jiguang/chat/activity/ForwardMsgActivity.java b/chatapp/src/main/java/jiguang/chat/activity/ForwardMsgActivity.java
index 75aa7f9b..561f3e44 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/ForwardMsgActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/ForwardMsgActivity.java
@@ -15,6 +15,7 @@
import cn.jpush.im.android.api.JMessageClient;
import cn.jpush.im.android.api.content.TextContent;
+import cn.jpush.im.android.api.enums.ConversationType;
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.Message;
import cn.jpush.im.android.api.options.MessageSendingOptions;
@@ -64,7 +65,7 @@ private void initView() {
private void initData() {
List conversationList = JMessageClient.getConversationList();
for (Conversation conv : conversationList) {
- if (!conv.getTargetId().equals("feedback_Android")) {
+ if (!conv.getTargetId().equals("feedback_Android") && conv.getType() != ConversationType.chatroom) {
forwardList.add(conv);
}
}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/FriendInfoActivity.java b/chatapp/src/main/java/jiguang/chat/activity/FriendInfoActivity.java
index 16c09f81..207cb7fd 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/FriendInfoActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/FriendInfoActivity.java
@@ -8,13 +8,14 @@
import com.activeandroid.query.Update;
+import org.greenrobot.eventbus.EventBus;
+
import cn.jpush.im.android.api.JMessageClient;
import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback;
import cn.jpush.im.android.api.callback.GetUserInfoCallback;
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.GroupInfo;
import cn.jpush.im.android.api.model.UserInfo;
-import cn.jpush.im.android.eventbus.EventBus;
import jiguang.chat.R;
import jiguang.chat.application.JGApplication;
import jiguang.chat.controller.FriendInfoController;
@@ -60,7 +61,8 @@ protected void onCreate(Bundle savedInstanceState) {
mTargetAppKey = JMessageClient.getMyInfo().getAppKey();
}
mFriendInfoView.initModel(this);
- mFriendInfoController = new FriendInfoController(mFriendInfoView, this);
+ int flags = getIntent().getFlags();
+ mFriendInfoController = new FriendInfoController(flags, this);
mFriendInfoView.setListeners(mFriendInfoController);
mFriendInfoView.setOnChangeListener(mFriendInfoController);
mIsFromContact = getIntent().getBooleanExtra("fromContact", false);
@@ -164,8 +166,6 @@ public void startChatActivity() {
.setConversation(conv)
.build());
}
- finish();
-
}
public UserInfo getUserInfo() {
diff --git a/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java b/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java
index 12034e26..459ca31b 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/FriendListActivity.java
@@ -17,12 +17,14 @@
import cn.jpush.im.android.api.JMessageClient;
import cn.jpush.im.android.api.content.TextContent;
+import cn.jpush.im.android.api.enums.ConversationType;
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.Message;
import cn.jpush.im.android.api.options.MessageSendingOptions;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.adapter.FriendListAdapter;
+import jiguang.chat.application.JGApplication;
import jiguang.chat.database.FriendEntry;
import jiguang.chat.database.UserEntry;
import jiguang.chat.utils.DialogCreator;
@@ -30,7 +32,7 @@
import jiguang.chat.utils.SharePreferenceManager;
import jiguang.chat.utils.pinyin.PinyinComparator;
import jiguang.chat.utils.sidebar.SideBar;
-import jiguang.chat.view.listview.StickyListHeadersListView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
/**
* Created by ${chenyn} on 2017/9/21.
@@ -87,10 +89,26 @@ public void onClick(View v) {
public void onItemClick(AdapterView> parent, View view, int position, long id) {
Object itemAtPosition = parent.getItemAtPosition(position);
FriendEntry friendEntry = (FriendEntry) itemAtPosition;
- if (getIntent().getBooleanExtra("isSingle", false)) {
- setBusinessCard(friendEntry, JMessageClient.getSingleConversation(getIntent().getStringExtra("userId")));
- } else {
- setBusinessCard(friendEntry, JMessageClient.getGroupConversation(getIntent().getLongExtra("groupId", 0)));
+ ConversationType convType = (ConversationType) getIntent().getSerializableExtra(JGApplication.CONV_TYPE);
+ String targetId = getIntent().getStringExtra(JGApplication.TARGET_ID);
+ String targetAppKey = getIntent().getStringExtra(JGApplication.TARGET_APP_KEY);
+ Conversation conv = null;
+ if (convType != null) {
+ switch (convType) {
+ case single:
+ conv = JMessageClient.getSingleConversation(targetId, targetAppKey);
+ break;
+ case group:
+ conv = JMessageClient.getGroupConversation(Long.valueOf(targetId));
+ break;
+ case chatroom:
+ conv = JMessageClient.getChatRoomConversation(Long.valueOf(targetId));
+ break;
+ default:
+ }
+ }
+ if (conv != null) {
+ setBusinessCard(friendEntry, conv);
}
}
});
@@ -133,6 +151,9 @@ public void gotResult(int i, String s) {
if (i == 0) {
SharePreferenceManager.setIsOpen(true);
Toast.makeText(FriendListActivity.this, "发送成功", Toast.LENGTH_SHORT).show();
+ Intent intent = new Intent();
+ intent.putExtra(JGApplication.MSG_JSON, textMessage.toJson());
+ FriendListActivity.this.setResult(RESULT_OK, intent);
finish();
} else {
HandleResponseCode.onHandle(FriendListActivity.this, i, false);
diff --git a/chatapp/src/main/java/jiguang/chat/activity/FriendSettingActivity.java b/chatapp/src/main/java/jiguang/chat/activity/FriendSettingActivity.java
index 9bc37dee..e5c9bb2a 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/FriendSettingActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/FriendSettingActivity.java
@@ -10,6 +10,8 @@
import android.widget.RelativeLayout;
import android.widget.TextView;
+import org.greenrobot.eventbus.EventBus;
+
import java.util.ArrayList;
import java.util.List;
@@ -17,7 +19,6 @@
import cn.jpush.im.android.api.callback.GetUserInfoCallback;
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.UserInfo;
-import cn.jpush.im.android.eventbus.EventBus;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.application.JGApplication;
diff --git a/chatapp/src/main/java/jiguang/chat/activity/GroupInfoActivity.java b/chatapp/src/main/java/jiguang/chat/activity/GroupInfoActivity.java
new file mode 100644
index 00000000..58023a9f
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/GroupInfoActivity.java
@@ -0,0 +1,112 @@
+package jiguang.chat.activity;
+
+import android.app.Dialog;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback;
+import cn.jpush.im.android.api.callback.GetGroupInfoCallback;
+import cn.jpush.im.android.api.model.GroupInfo;
+import jiguang.chat.R;
+import jiguang.chat.utils.DialogCreator;
+
+/**
+ * Created by ${chenyn} on 2017/11/6.
+ */
+
+public class GroupInfoActivity extends BaseActivity {
+
+ private ImageView mIv_groupAvatar;
+ private TextView mTv_groupName;
+ private TextView mTv_groupId;
+ private TextView mTv_groupOwner;
+ private TextView mTv_groupMember;
+ private TextView mTv_groupDesc;
+ private Button mBtn_apply;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_group_info);
+ initTitle(true, true, "群资料", "", false, "");
+ mIv_groupAvatar = (ImageView) findViewById(R.id.iv_groupAvatar);
+ mTv_groupName = (TextView) findViewById(R.id.tv_groupName);
+ mTv_groupId = (TextView) findViewById(R.id.tv_groupId);
+ mTv_groupOwner = (TextView) findViewById(R.id.tv_groupOwner);
+ mTv_groupMember = (TextView) findViewById(R.id.tv_groupMember);
+ mTv_groupDesc = (TextView) findViewById(R.id.tv_groupDesc);
+ mBtn_apply = (Button) findViewById(R.id.btn_apply);
+
+ initData();
+ }
+
+ private void initData() {
+ Intent intent = getIntent();
+ if (intent.getFlags() != 1) {
+ if (intent.getStringExtra("groupAvatar") != null) {
+ mIv_groupAvatar.setImageBitmap(BitmapFactory.decodeFile(intent.getStringExtra("groupAvatar")));
+ }
+ mTv_groupName.setText(intent.getStringExtra("groupName"));
+ mTv_groupId.setText(intent.getLongExtra("groupId", 0) + "");
+ mTv_groupOwner.setText(intent.getStringExtra("groupOwner"));
+ mTv_groupMember.setText(intent.getStringExtra("groupMember") + "人");
+ if (TextUtils.isEmpty(intent.getStringExtra("groupDesc"))) {
+ mTv_groupDesc.setText("暂无描述");
+ } else {
+ mTv_groupDesc.setText(intent.getStringExtra("groupDesc"));
+ }
+ mBtn_apply.setOnClickListener(v -> {
+ //申请入群
+ Intent start = new Intent(GroupInfoActivity.this, VerificationGroupActivity.class);
+ //传群组id过去申请入群
+ start.putExtra("openGroupID", intent.getLongExtra("groupId", 0));
+ startActivity(start);
+
+ });
+ } else {
+ Dialog loadingDialog = DialogCreator.createLoadingDialog(GroupInfoActivity.this, "正在加载...");
+ loadingDialog.show();
+ String groupId = intent.getStringExtra("groupId");
+ mBtn_apply.setVisibility(View.GONE);
+ JMessageClient.getGroupInfo(Long.parseLong(groupId), new GetGroupInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, GroupInfo groupInfo) {
+ loadingDialog.dismiss();
+ if (i == 0) {
+ groupInfo.getAvatarBitmap(new GetAvatarBitmapCallback() {
+ @Override
+ public void gotResult(int i, String s, Bitmap bitmap) {
+ if (i == 0) {
+ mIv_groupAvatar.setImageBitmap(bitmap);
+ } else {
+ mIv_groupAvatar.setImageResource(R.drawable.group);
+ }
+ }
+ });
+
+ mTv_groupName.setText(groupInfo.getGroupName());
+ mTv_groupId.setText(groupInfo.getGroupID() + "");
+ mTv_groupOwner.setText(groupInfo.getGroupOwner());
+ mTv_groupMember.setText(groupInfo.getGroupMembers().size() + "");
+ if (!TextUtils.isEmpty(groupInfo.getGroupDescription())) {
+ mTv_groupDesc.setText(groupInfo.getGroupDescription());
+ } else {
+ mTv_groupDesc.setText("暂无描述");
+ }
+ }
+ }
+ });
+
+ }
+
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/GroupMemberListActivity.java b/chatapp/src/main/java/jiguang/chat/activity/GroupMemberListActivity.java
new file mode 100644
index 00000000..a494fbef
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/GroupMemberListActivity.java
@@ -0,0 +1,129 @@
+package jiguang.chat.activity;
+
+import android.content.Intent;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import java.util.Collections;
+import java.util.List;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetUserInfoCallback;
+import cn.jpush.im.android.api.model.Conversation;
+import cn.jpush.im.android.api.model.GroupInfo;
+import cn.jpush.im.android.api.model.UserInfo;
+import jiguang.chat.R;
+import jiguang.chat.adapter.GroupMemberListAdapter;
+import jiguang.chat.application.JGApplication;
+import jiguang.chat.utils.GroupMemberListComparator;
+import jiguang.chat.utils.sidebar.SideBar;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
+
+/**
+ * Created by ${chenyn} on 2017/11/3.
+ */
+
+public class GroupMemberListActivity extends BaseActivity {
+
+ private StickyListHeadersListView mGroup_listView;
+ private long mGroupId;
+ private List mMemberInfoList;
+ private GroupInfo mGroupInfo;
+ private LinearLayout mLl_groupSearch;
+ private ImageView mIv_ownerAvatar;
+ private TextView mTv_ownerName;
+ private TextView mTv_back;
+ private GroupMemberListAdapter mListAdapter;
+ private SideBar mSideBar;
+ private TextView mLetterHintTv;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_group_member_list);
+ initView();
+ initData();
+ }
+
+ private void initData() {
+ mGroupId = getIntent().getLongExtra(JGApplication.GROUP_ID, 0);
+
+ final Conversation conv = JMessageClient.getGroupConversation(mGroupId);
+ mGroupInfo = (GroupInfo) conv.getTargetInfo();
+ mMemberInfoList = mGroupInfo.getGroupMembers();
+
+ //设置群主头像和名字
+ JMessageClient.getUserInfo(mGroupInfo.getGroupOwner(), new GetUserInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, UserInfo userInfo) {
+ if (i == 0) {
+ if (userInfo.getAvatarFile() != null) {
+ mIv_ownerAvatar.setImageBitmap(BitmapFactory.decodeFile(userInfo.getAvatarFile().getAbsolutePath()));
+ }
+ mTv_ownerName.setText(userInfo.getDisplayName());
+ }
+ }
+ });
+
+ Collections.sort(mMemberInfoList, new GroupMemberListComparator());
+ mListAdapter = new GroupMemberListAdapter(this, mMemberInfoList, mGroupId);
+ mGroup_listView.setAdapter(mListAdapter);
+
+ mLl_groupSearch.setOnClickListener(v -> {
+ Intent intent = new Intent(GroupMemberListActivity.this, SearchGroupActivity.class);
+ intent.setFlags(1);
+ JGApplication.mSearchGroup = null;
+ JGApplication.mSearchGroup = mMemberInfoList;
+ startActivity(intent);
+ });
+
+ mTv_back.setOnClickListener(v -> finish());
+
+ mSideBar.setOnTouchingLetterChangedListener(s -> {
+ int position = mListAdapter.getSectionForLetter(s);
+ if (position != -1 && position < mListAdapter.getCount()) {
+ //设置滑动sidebar时listView滑动到指定位置
+ mGroup_listView.setSelection(position);
+ }
+ });
+
+ //点击群成员列表,跳转详情界面
+ mGroup_listView.setOnItemClickListener((parent, view, position, id) -> {
+ Object itemAtPosition = parent.getItemAtPosition(position);
+ if (itemAtPosition instanceof UserInfo) {
+ UserInfo info = (UserInfo) itemAtPosition;
+ Intent intent = new Intent();
+ intent.setClass(GroupMemberListActivity.this, GroupUserInfoActivity.class);
+ intent.putExtra("groupID", mGroupId);
+ intent.putExtra("groupOwner", mGroupInfo.getGroupOwner());
+ intent.putExtra("groupUserName", info.getUserName());
+ startActivity(intent);
+ }
+ });
+ }
+
+ private void initView() {
+ mGroup_listView = (StickyListHeadersListView) findViewById(R.id.group_listView);
+ View headerOwner = View.inflate(this, R.layout.header_list_group_member, null);
+ mLl_groupSearch = headerOwner.findViewById(R.id.ll_groupSearch);
+ mIv_ownerAvatar = headerOwner.findViewById(R.id.iv_ownerAvatar);
+ mTv_ownerName = headerOwner.findViewById(R.id.tv_ownerName);
+ mTv_back = (TextView) findViewById(R.id.tv_back);
+ mSideBar = (SideBar) findViewById(R.id.sidebar);
+ mGroup_listView.addHeaderView(headerOwner);
+ mLetterHintTv = (TextView) findViewById(R.id.letter_hint_tv);
+ mSideBar.setTextView(mLetterHintTv);
+ mSideBar.bringToFront();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mListAdapter.notifyDataSetChanged();
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/GroupNotFriendActivity.java b/chatapp/src/main/java/jiguang/chat/activity/GroupNotFriendActivity.java
index 6238b38f..2edf5afe 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/GroupNotFriendActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/GroupNotFriendActivity.java
@@ -13,6 +13,8 @@
import android.widget.RelativeLayout;
import android.widget.TextView;
+import org.greenrobot.eventbus.EventBus;
+
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -21,7 +23,6 @@
import cn.jpush.im.android.api.callback.GetUserInfoCallback;
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.UserInfo;
-import cn.jpush.im.android.eventbus.EventBus;
import jiguang.chat.R;
import jiguang.chat.application.JGApplication;
import jiguang.chat.entity.Event;
diff --git a/chatapp/src/main/java/jiguang/chat/activity/GroupUserInfoActivity.java b/chatapp/src/main/java/jiguang/chat/activity/GroupUserInfoActivity.java
new file mode 100644
index 00000000..5582ffe4
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/GroupUserInfoActivity.java
@@ -0,0 +1,172 @@
+package jiguang.chat.activity;
+
+import android.app.Dialog;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback;
+import cn.jpush.im.android.api.callback.GetUserInfoCallback;
+import cn.jpush.im.android.api.model.Conversation;
+import cn.jpush.im.android.api.model.UserInfo;
+import jiguang.chat.R;
+import jiguang.chat.application.JGApplication;
+import jiguang.chat.entity.Event;
+import jiguang.chat.entity.EventType;
+import jiguang.chat.utils.DialogCreator;
+
+/**
+ * Created by ${chenyn} on 2017/11/27.
+ */
+
+public class GroupUserInfoActivity extends BaseActivity {
+
+ private ImageView mIv_more;
+ private ImageView mIv_userAvatar;
+ private TextView mTv_displayName;
+ private TextView mTv_sign;
+ private TextView mTv_userName;
+ private TextView mTv_nick;
+ private TextView mTv_gender;
+ private TextView mTv_birthday;
+ private TextView mTv_address;
+ private Button mBtn_send_message;
+ private String mUserName;
+ private String mAppKey = JMessageClient.getMyInfo().getAppKey(); // 默认使用本应用appkey
+ public static final String IS_FROM_GROUP = "is_from_group";
+ private boolean isFromGroup = true;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.group_user_info);
+ isFromGroup = getIntent().getBooleanExtra(IS_FROM_GROUP, true);
+
+ initView();
+ initData();
+ }
+
+ private void initData() {
+ Dialog dialog = DialogCreator.createLoadingDialog(GroupUserInfoActivity.this, "正在加载...");
+ dialog.show();
+ JMessageClient.getUserInfo(mUserName, mAppKey, new GetUserInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, UserInfo userInfo) {
+ dialog.dismiss();
+ if (i == 0) {
+ userInfo.getAvatarBitmap(new GetAvatarBitmapCallback() {
+ @Override
+ public void gotResult(int i, String s, Bitmap bitmap) {
+ if (i == 0) {
+ mIv_userAvatar.setImageBitmap(bitmap);
+ } else {
+ mIv_userAvatar.setImageResource(R.drawable.jmui_head_icon);
+ }
+ }
+ });
+
+ mTv_displayName.setText(userInfo.getDisplayName());
+ mTv_sign.setText(userInfo.getSignature());
+ mTv_userName.setText(userInfo.getUserName());
+ mTv_nick.setText(userInfo.getNickname() == null ? "" : userInfo.getNickname());
+ UserInfo.Gender gender = userInfo.getGender();
+ if (gender.equals(UserInfo.Gender.male)) {
+ mTv_gender.setText("男");
+ } else if (gender.equals(UserInfo.Gender.female)) {
+ mTv_gender.setText("女");
+ } else {
+ mTv_gender.setText("保密");
+ }
+ mTv_birthday.setText(getBirthday(userInfo));
+ mTv_address.setText(userInfo.getRegion());
+ mBtn_send_message.setOnClickListener(v -> {
+ Intent intent = new Intent();
+ intent.setClass(GroupUserInfoActivity.this, ChatActivity.class);
+ //创建会话
+ intent.putExtra(JGApplication.TARGET_ID, userInfo.getUserName());
+ intent.putExtra(JGApplication.TARGET_APP_KEY, userInfo.getAppKey());
+ String notename = userInfo.getNotename();
+ if (TextUtils.isEmpty(notename)) {
+ notename = userInfo.getNickname();
+ if (TextUtils.isEmpty(notename)) {
+ notename = userInfo.getUserName();
+ }
+ }
+ intent.putExtra(JGApplication.CONV_TITLE, notename);
+ Conversation conv = JMessageClient.getSingleConversation(userInfo.getUserName(), userInfo.getAppKey());
+ //如果会话为空,使用EventBus通知会话列表添加新会话
+ if (conv == null) {
+ conv = Conversation.createSingleConversation(userInfo.getUserName(), userInfo.getAppKey());
+ EventBus.getDefault().post(new Event.Builder()
+ .setType(EventType.createConversation)
+ .setConversation(conv)
+ .build());
+ }
+ startActivity(intent);
+ });
+ }
+ }
+ });
+
+ mIv_more.setOnClickListener(v -> {
+ Intent intent = new Intent(GroupUserInfoActivity.this, SetGroupSilenceActivity.class);
+ long groupID = getIntent().getLongExtra("groupID", 0);
+ intent.putExtra("groupID", groupID);
+ intent.putExtra("userName", mUserName);
+ startActivity(intent);
+ });
+
+ }
+
+ private void initView() {
+ if (isFromGroup) {
+ mUserName = getIntent().getStringExtra("groupUserName");
+ } else {
+ mUserName = getIntent().getStringExtra(JGApplication.NAME);
+ mAppKey = getIntent().getStringExtra(JGApplication.TARGET_APP_KEY);
+ }
+ findViewById(R.id.return_btn).setOnClickListener(v -> finish());
+ String groupOwner = getIntent().getStringExtra("groupOwner");
+ mIv_more = (ImageView) findViewById(R.id.iv_more);
+ if (isFromGroup && groupOwner.equals(JMessageClient.getMyInfo().getUserName())) {
+ mIv_more.setVisibility(View.VISIBLE);
+ } else {
+ mIv_more.setVisibility(View.GONE);
+ }
+
+ mIv_userAvatar = (ImageView) findViewById(R.id.iv_userAvatar);
+ mTv_displayName = (TextView) findViewById(R.id.tv_displayName);
+ mTv_sign = (TextView) findViewById(R.id.tv_sign);
+ mTv_userName = (TextView) findViewById(R.id.tv_userName);
+ mTv_nick = (TextView) findViewById(R.id.tv_nick);
+ mTv_gender = (TextView) findViewById(R.id.tv_gender);
+ mTv_birthday = (TextView) findViewById(R.id.tv_birthday);
+ mTv_address = (TextView) findViewById(R.id.tv_address);
+ mBtn_send_message = (Button) findViewById(R.id.btn_send_message);
+ if (!isFromGroup) {
+ mBtn_send_message.setVisibility(View.GONE);
+ }
+ }
+
+ public String getBirthday(UserInfo info) {
+ long birthday = info.getBirthday();
+ if (birthday == 0) {
+ return "";
+ } else {
+ Date date = new Date(birthday);
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ return dateFormat.format(date);
+ }
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/MainActivity.java b/chatapp/src/main/java/jiguang/chat/activity/MainActivity.java
index 343c077f..e5b116d9 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/MainActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/MainActivity.java
@@ -1,9 +1,17 @@
package jiguang.chat.activity;
+import android.Manifest;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.view.KeyEvent;
+import android.widget.Toast;
+
+import com.yanzhenjie.permission.AndPermission;
+import com.yanzhenjie.permission.PermissionListener;
+
+import java.util.ArrayList;
+import java.util.List;
import cn.jiguang.api.JCoreInterface;
import jiguang.chat.R;
@@ -13,13 +21,14 @@
public class MainActivity extends FragmentActivity {
private MainController mMainController;
private MainView mMainView;
+ private List permissions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
-
+ requestPermission();
mMainView = (MainView) findViewById(R.id.main_view);
mMainView.initModule();
mMainController = new MainController(mMainView, this);
@@ -28,6 +37,34 @@ protected void onCreate(Bundle savedInstanceState) {
mMainView.setOnPageChangeListener(mMainController);
}
+ private void requestPermission() {
+ permissions = new ArrayList<>();
+ permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+ permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
+ permissions.add(Manifest.permission.CAMERA);
+ permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
+ permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
+ permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
+ permissions.add(Manifest.permission.ACCESS_WIFI_STATE);
+ permissions.add(Manifest.permission.RECORD_AUDIO);
+ if (AndPermission.hasPermission(this, permissions)) {
+ return;
+ }else {
+ AndPermission.with(this)
+ .requestCode(100)
+ .permission(Manifest.permission.READ_EXTERNAL_STORAGE,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ Manifest.permission.CAMERA,
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION,
+ Manifest.permission.ACCESS_WIFI_STATE,
+ Manifest.permission.RECORD_AUDIO)
+ .callback(listener)
+ .start();
+ }
+ }
+
public FragmentManager getSupportFragmentManger() {
return getSupportFragmentManager();
}
@@ -53,4 +90,33 @@ protected void onDestroy() {
public boolean onKeyDown(int keyCode, KeyEvent event) {
return keyCode == KeyEvent.KEYCODE_BACK;
}
+
+
+ private PermissionListener listener = new PermissionListener() {
+ @Override
+ public void onSucceed(int requestCode, List grantedPermissions) {
+ // Successfully.
+ if(requestCode == 100) {
+ Toast.makeText(MainActivity.this, "成功", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ @Override
+ public void onFailed(int requestCode, List deniedPermissions) {
+ // Failure.
+
+ }
+ };
+
+// private RationaleListener rationaleListener = (requestCode, rationale) -> {
+// AlertDialog.newBuilder(this)
+// .setMessage("正常使用JChat需要您打开相关权限.")
+// .setPositiveButton("是", (dialog, which) -> {
+// rationale.resume();
+// })
+// .setNegativeButton("否", (dialog, which) -> {
+// rationale.cancel();
+// }).show();
+// };
+
}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/NickSignActivity.java b/chatapp/src/main/java/jiguang/chat/activity/NickSignActivity.java
index 78f892ee..deae2932 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/NickSignActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/NickSignActivity.java
@@ -1,6 +1,7 @@
package jiguang.chat.activity;
import android.content.Intent;
+import android.graphics.Color;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputFilter;
@@ -19,15 +20,19 @@
*/
public class NickSignActivity extends BaseActivity {
+ public static final String TYPE = "type";
+ public static final String COUNT = "count";
+ public static final String DESC = "desc";
+
+ public enum Type {
+ GROUP_NAME, GROUP_DESC, PERSON_SIGN, PERSON_NICK, CHAT_ROOM_NAME, CHAT_ROOM_DESC;
+ }
private EditText mEd_sign;
+ private TextView mTv_title;
private TextView mTv_count;
private LinearLayout mLl_nickSign;
- private static final int SIGN_COUNT = 250;
- private static final int NICK_COUNT = 64;
- private static final int GROUP_DESC = 250;
- private static final int GROUP_NAME = 64;
private Button mJmui_commit_btn;
@Override
@@ -37,43 +42,78 @@ protected void onCreate(Bundle savedInstanceState) {
initView();
Intent intent = getIntent();
- if (intent.getFlags() == PersonalActivity.FLAGS_SIGN) {
- initViewSign("个性签名", SIGN_COUNT);
- initData(SIGN_COUNT);
- } else if (intent.getFlags() == PersonalActivity.FLAGS_NICK) {
- initViewNick("修改昵称", NICK_COUNT);
- initData(NICK_COUNT);
- } else if (intent.getFlags() == ChatDetailActivity.FLAGS_GROUP_DESC) {
- initViewSign("群描述", GROUP_DESC);
- initData(GROUP_DESC);
- } else if (intent.getFlags() == ChatDetailActivity.FLAGS_GROUP_NAME) {
- initViewNick("群名称", GROUP_NAME);
- initData(GROUP_NAME);
+ Type type = (Type) intent.getSerializableExtra(TYPE);
+ int count = intent.getIntExtra(COUNT, 0);
+ switch (type) {
+ case PERSON_SIGN:
+ initViewSign("个性签名", count);
+ break;
+ case PERSON_NICK:
+ initViewNick("修改昵称", count);
+ break;
+ case GROUP_DESC:
+ initViewSign("群描述", count);
+ break;
+ case GROUP_NAME:
+ initViewNick("群名称", count);
+ break;
+ case CHAT_ROOM_NAME:
+ case CHAT_ROOM_DESC:
+ LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mEd_sign.getLayoutParams();
+ layoutParams.leftMargin = (int) (10 * mDensity);
+ layoutParams.rightMargin = (int) (10 * mDensity);
+ layoutParams.topMargin = (int) (5 * mDensity);
+ if (type == Type.CHAT_ROOM_NAME) {
+ initViewNick("聊天室名称", count);
+ mTv_title.setText("聊天室名称");
+ layoutParams.bottomMargin = (int) (20 * mDensity);
+ } else {
+ initViewSign("聊天室介绍", count);
+ mTv_title.setText("聊天室介绍");
+ layoutParams.bottomMargin = (int) (30 * mDensity);
+ }
+ mTv_count.setVisibility(View.GONE);
+ mTv_title.setVisibility(View.VISIBLE);
+ mEd_sign.setFocusable(false);
+ mEd_sign.setFocusableInTouchMode(false);
+ mEd_sign.setBackgroundColor(Color.parseColor("#FFE8EDF3"));
+ mEd_sign.setLayoutParams(layoutParams);
+ mLl_nickSign.setBackgroundColor(Color.WHITE);
+ mJmui_commit_btn.setVisibility(View.GONE);
+ break;
+
+ default:
+ break;
}
- initListener(intent.getFlags());
+ initData(count);
+ initListener(type);
}
- private void initListener(final int flags) {
+ private void initListener(Type type) {
mJmui_commit_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String sign = mEd_sign.getText().toString();
Intent intent = new Intent();
- if (flags == PersonalActivity.FLAGS_NICK) {//3
- intent.putExtra(PersonalActivity.NICK_NAME_KEY, sign);
- setResult(PersonalActivity.NICK_NAME, intent);//4
- } else if (flags == PersonalActivity.FLAGS_SIGN) {//2
- intent.putExtra(PersonalActivity.SIGN_KEY, sign);
- setResult(PersonalActivity.SIGN, intent);//1
-
- } else if (flags == ChatDetailActivity.FLAGS_GROUP_DESC) {//71
- intent.putExtra(ChatDetailActivity.GROUP_DESC_KEY, sign);
- setResult(ChatDetailActivity.GROUP_DESC, intent);//70
-
- } else if (flags == ChatDetailActivity.FLAGS_GROUP_NAME) {//73
- intent.putExtra(ChatDetailActivity.GROUP_NAME_KEY, sign);
- setResult(ChatDetailActivity.GROUP_NAME, intent);//72
-
+ switch (type) {
+ case PERSON_NICK:
+ intent.putExtra(PersonalActivity.NICK_NAME_KEY, sign);
+ setResult(PersonalActivity.NICK_NAME, intent);//4
+ break;
+ case PERSON_SIGN:
+ intent.putExtra(PersonalActivity.SIGN_KEY, sign);
+ setResult(PersonalActivity.SIGN, intent);//1
+ break;
+ case GROUP_DESC:
+ intent.putExtra(ChatDetailActivity.GROUP_DESC_KEY, sign);
+ setResult(ChatDetailActivity.GROUP_DESC, intent);//70
+ break;
+ case GROUP_NAME:
+ intent.putExtra(ChatDetailActivity.GROUP_NAME_KEY, sign);
+ setResult(ChatDetailActivity.GROUP_NAME, intent);//72
+ break;
+ default:
+ break;
}
//做更新动作
finish();
@@ -108,20 +148,8 @@ private void initView() {
mLl_nickSign = (LinearLayout) findViewById(R.id.ll_nickSign);
mTv_count = (TextView) findViewById(R.id.tv_count);
mJmui_commit_btn = (Button) findViewById(R.id.jmui_commit_btn);
-
- if (getIntent().getStringExtra("group_name") != null) {
- mEd_sign.setText(getIntent().getStringExtra("group_name"));
- }
- if (getIntent().getStringExtra("group_desc") != null) {
- mEd_sign.setText(getIntent().getStringExtra("group_desc"));
- }
- if (getIntent().getStringExtra("old_nick") != null) {
- mEd_sign.setText(getIntent().getStringExtra("old_nick"));
- }
- if (getIntent().getStringExtra("old_sign") != null) {
- mEd_sign.setText(getIntent().getStringExtra("old_sign"));
- }
-
+ mTv_title = (TextView) findViewById(R.id.tv_title);
+ mEd_sign.setText(getIntent().getStringExtra(DESC));
mEd_sign.setSelection(mEd_sign.getText().length());
}
@@ -135,11 +163,11 @@ private void initViewSign(String str, int flag) {
mTv_count.setText(flag - length + "");
}
- private void initViewNick(String str, int flag) {
+ private void initViewNick(String str, int count) {
initTitle(true, true, str, "", true, "完成");
- mEd_sign.setFilters(new InputFilter[] {new MyLengthFilter(flag)});
+ mEd_sign.setFilters(new InputFilter[] {new MyLengthFilter(count)});
int length = mEd_sign.getText().toString().getBytes().length;
- mTv_count.setText(flag - length + "");
+ mTv_count.setText(count - length + "");
int width = LinearLayout.LayoutParams.MATCH_PARENT;
diff --git a/chatapp/src/main/java/jiguang/chat/activity/PersonalActivity.java b/chatapp/src/main/java/jiguang/chat/activity/PersonalActivity.java
index 856223c0..be8862e9 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/PersonalActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/PersonalActivity.java
@@ -40,13 +40,14 @@
public class PersonalActivity extends BaseActivity implements SelectAddressInterface, View.OnClickListener {
public static final int SIGN = 1;
- public static final int FLAGS_SIGN = 2;
public static final String SIGN_KEY = "sign_key";
public static final int NICK_NAME = 4;
- public static final int FLAGS_NICK = 3;
public static final String NICK_NAME_KEY = "nick_name_key";
+ private static final int SIGN_COUNT = 250;
+ private static final int NICK_COUNT = 64;
+
private RelativeLayout mRl_cityChoose;
private TextView mTv_city;
private SelectAddressDialog dialog;
@@ -190,14 +191,16 @@ public void onClick(View v) {
break;
case R.id.rl_nickName:
//昵称
- intent.setFlags(FLAGS_NICK);
- intent.putExtra("old_nick", mMyInfo.getNickname());
+ intent.putExtra(NickSignActivity.TYPE, NickSignActivity.Type.PERSON_NICK);
+ intent.putExtra(NickSignActivity.COUNT, NICK_COUNT);
+ intent.putExtra(NickSignActivity.DESC, mMyInfo.getNickname());
startActivityForResult(intent, NICK_NAME);
break;
case R.id.sign:
//签名
- intent.setFlags(FLAGS_SIGN);
- intent.putExtra("old_sign", mMyInfo.getSignature());
+ intent.putExtra(NickSignActivity.TYPE, NickSignActivity.Type.PERSON_SIGN);
+ intent.putExtra(NickSignActivity.COUNT, SIGN_COUNT);
+ intent.putExtra(NickSignActivity.DESC, mMyInfo.getSignature());
startActivityForResult(intent, SIGN);
break;
case R.id.rl_gender:
diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchAddOpenGroupActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchAddOpenGroupActivity.java
new file mode 100644
index 00000000..49087609
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/SearchAddOpenGroupActivity.java
@@ -0,0 +1,139 @@
+package jiguang.chat.activity;
+
+import android.app.ProgressDialog;
+import android.content.Intent;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetGroupInfoCallback;
+import cn.jpush.im.android.api.model.GroupInfo;
+import jiguang.chat.R;
+import jiguang.chat.utils.photochoose.SelectableRoundedImageView;
+
+/**
+ * Created by ${chenyn} on 2017/11/6.
+ */
+
+public class SearchAddOpenGroupActivity extends BaseActivity {
+
+ private EditText mEt_searchGroup;
+ private Button mBtn_search;
+ private ImageView mIv_clear;
+ private LinearLayout mLl_group;
+ private SelectableRoundedImageView mSearch_group_avatar;
+ private TextView mTv_groupName;
+ private TextView mTv_groupID;
+ private TextView mTv_groupDesc;
+ private GroupInfo mGroupInfo;
+ private TextView mTv_searchResult;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_search_add_open_group);
+
+ mEt_searchGroup = (EditText) findViewById(R.id.et_searchGroup);
+ mBtn_search = (Button) findViewById(R.id.btn_search);
+ mIv_clear = (ImageView) findViewById(R.id.iv_clear);
+
+ mLl_group = (LinearLayout) findViewById(R.id.ll_group);
+ mSearch_group_avatar = (SelectableRoundedImageView) findViewById(R.id.search_group_avatar);
+ mTv_groupName = (TextView) findViewById(R.id.tv_groupName);
+ mTv_groupID = (TextView) findViewById(R.id.tv_groupID);
+ mTv_groupDesc = (TextView) findViewById(R.id.tv_groupDesc);
+ mTv_searchResult = (TextView) findViewById(R.id.tv_searchResult);
+
+ initTitle(true, true, "加入公开群", "", false, "");
+
+ initData();
+ }
+
+ private void initData() {
+ mEt_searchGroup.addTextChangedListener(new TextChange());
+ mIv_clear.setOnClickListener(v -> mEt_searchGroup.setText(""));
+ ProgressDialog dialog = new ProgressDialog(SearchAddOpenGroupActivity.this);
+ dialog.setMessage("正在加载...");
+ dialog.setCanceledOnTouchOutside(false);
+ mBtn_search.setOnClickListener(v -> {
+ if (mEt_searchGroup.getText() != null) {
+ String groupId = mEt_searchGroup.getText().toString().trim();
+ JMessageClient.getGroupInfo(Long.parseLong(groupId), new GetGroupInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, GroupInfo groupInfo) {
+ dialog.dismiss();
+ if (i == 0 && (groupInfo.getGroupFlag() == 2)) {
+ mGroupInfo = groupInfo;
+ mTv_searchResult.setVisibility(View.GONE);
+ mLl_group.setVisibility(View.VISIBLE);
+
+ if (groupInfo.getAvatarFile() != null) {
+ mSearch_group_avatar.setImageBitmap(BitmapFactory.decodeFile(groupInfo.getAvatarFile().getAbsolutePath()));
+ } else {
+ mSearch_group_avatar.setImageResource(R.drawable.jmui_head_icon);
+ }
+ mTv_groupName.setText(groupInfo.getGroupName());
+ mTv_groupID.setText(groupInfo.getGroupID() + "");
+ mTv_groupDesc.setText(groupInfo.getGroupDescription());
+ } else {
+ mTv_searchResult.setVisibility(View.VISIBLE);
+ mLl_group.setVisibility(View.GONE);
+ }
+ }
+ });
+ } else {
+ Toast.makeText(SearchAddOpenGroupActivity.this, "请输入群组id", Toast.LENGTH_SHORT).show();
+ }
+ });
+
+ mLl_group.setOnClickListener(v -> {
+ //申请加入群
+ Intent intent = new Intent(SearchAddOpenGroupActivity.this, GroupInfoActivity.class);
+ if (mGroupInfo != null) {
+ if (mGroupInfo.getAvatarFile() != null) {
+ intent.putExtra("groupAvatar", mGroupInfo.getAvatarFile().getAbsolutePath());
+ }
+ intent.putExtra("groupName", mGroupInfo.getGroupName());
+ intent.putExtra("groupId", mGroupInfo.getGroupID());
+ intent.putExtra("groupOwner", mGroupInfo.getGroupOwner());
+ intent.putExtra("groupMember", mGroupInfo.getGroupMembers().size() + "");
+ intent.putExtra("groupDesc", mGroupInfo.getGroupDescription());
+ startActivity(intent);
+ }
+ });
+ }
+
+ private class TextChange implements TextWatcher {
+
+ @Override
+ public void afterTextChanged(Editable arg0) {
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
+ int arg3) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence cs, int start, int before,
+ int count) {
+ boolean feedback = mEt_searchGroup.getText().length() > 0;
+ if (feedback) {
+ mIv_clear.setVisibility(View.VISIBLE);
+ mBtn_search.setEnabled(true);
+ } else {
+ mIv_clear.setVisibility(View.GONE);
+ mBtn_search.setEnabled(false);
+ }
+ }
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchChatRoomActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchChatRoomActivity.java
new file mode 100644
index 00000000..4dca1887
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/SearchChatRoomActivity.java
@@ -0,0 +1,153 @@
+package jiguang.chat.activity;
+
+import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.Collections;
+import java.util.List;
+
+import cn.jpush.im.android.api.ChatRoomManager;
+import cn.jpush.im.android.api.callback.RequestCallback;
+import cn.jpush.im.android.api.model.ChatRoomInfo;
+import jiguang.chat.R;
+import jiguang.chat.utils.CommonUtils;
+
+/**
+ * Created by ${chenyn} on 2017/11/9.
+ */
+
+public class SearchChatRoomActivity extends BaseActivity {
+
+ private LinearLayout mLl_chatRoomItem;
+ private ImageView mIv_chatRoomAvatar;
+ private TextView mTv_chatRoomName;
+ private TextView mTv_chatRoomDesc;
+ private EditText mSearchEditText;
+ private LinearLayout mAc_iv_press_back;
+ private TextView mTv_search;
+ private long mRoomID;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_search_chat_room);
+
+ initView();
+ initData();
+ }
+
+ @SuppressLint("ClickableViewAccessibility")
+ private void initData() {
+ //清空EditText
+ mSearchEditText.setOnTouchListener((v, event) -> {
+ final int DRAWABLE_RIGHT = 2;
+ if (event.getAction() == MotionEvent.ACTION_UP) {
+ if (event.getRawX() >= (mSearchEditText.getRight() - 2 * mSearchEditText.getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {
+ mSearchEditText.setText("");
+ mSearchEditText.clearFocus();
+ mLl_chatRoomItem.setVisibility(View.GONE);
+ return true;
+ }
+ }
+ return false;
+ });
+
+
+ mSearchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_UNSPECIFIED) {
+
+ String keytag = mSearchEditText.getText().toString().trim();
+
+ if (TextUtils.isEmpty(keytag)) {
+ Toast.makeText(SearchChatRoomActivity.this, "请输入聊天室ID", Toast.LENGTH_SHORT).show();
+ } else {
+ String roomId = mSearchEditText.getText().toString().trim();
+ try {
+ long id = Long.parseLong(roomId);
+ ChatRoomManager.getChatRoomInfos(Collections.singleton(id), new RequestCallback>() {
+ @Override
+ public void gotResult(int i, String s, List chatRoomInfos) {
+ if (i == 0) {
+ mRoomID = chatRoomInfos.get(0).getRoomID();
+ mLl_chatRoomItem.setVisibility(View.VISIBLE);
+ mTv_chatRoomDesc.setText(chatRoomInfos.get(0).getDescription());
+ mTv_chatRoomName.setText(chatRoomInfos.get(0).getName());
+ }else {
+ mLl_chatRoomItem.setVisibility(View.GONE);
+ Toast.makeText(SearchChatRoomActivity.this, "搜索的聊天室不存在", Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+ } catch (NumberFormatException e) {
+ Toast.makeText(SearchChatRoomActivity.this, "搜索的聊天室不存在", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+ return true;
+ }
+ });
+
+ mAc_iv_press_back.setOnClickListener(v -> {
+ finish();
+ CommonUtils.hideKeyboard(SearchChatRoomActivity.this);
+ });
+ mTv_search.setOnClickListener(v -> {
+ if (!TextUtils.isEmpty(mSearchEditText.getText())) {
+ String roomId = mSearchEditText.getText().toString().trim();
+ try {
+ long id = Long.parseLong(roomId);
+ ChatRoomManager.getChatRoomInfos(Collections.singleton(id), new RequestCallback>() {
+ @Override
+ public void gotResult(int i, String s, List chatRoomInfos) {
+ if (i == 0) {
+ mRoomID = chatRoomInfos.get(0).getRoomID();
+ mLl_chatRoomItem.setVisibility(View.VISIBLE);
+ mTv_chatRoomDesc.setText(chatRoomInfos.get(0).getDescription());
+ mTv_chatRoomName.setText(chatRoomInfos.get(0).getName());
+ }else {
+ mLl_chatRoomItem.setVisibility(View.GONE);
+ Toast.makeText(SearchChatRoomActivity.this, "搜索的聊天室不存在", Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+ } catch (NumberFormatException e) {
+ Toast.makeText(SearchChatRoomActivity.this, "搜索的聊天室不存在", Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ Toast.makeText(SearchChatRoomActivity.this, "请输入聊天室ID", Toast.LENGTH_SHORT).show();
+ }
+ });
+
+ mLl_chatRoomItem.setOnClickListener(v -> {
+ Intent intent = new Intent(SearchChatRoomActivity.this, ChatRoomDetailActivity.class);
+ intent.putExtra("chatRoomId", mRoomID);
+ startActivity(intent);
+ });
+
+ }
+
+ private void initView() {
+ mLl_chatRoomItem = (LinearLayout) findViewById(R.id.ll_chatRoomItem);
+ mIv_chatRoomAvatar = (ImageView) findViewById(R.id.iv_chatRoomAvatar);
+ mTv_chatRoomName = (TextView) findViewById(R.id.tv_chatRoomName);
+ mTv_chatRoomDesc = (TextView) findViewById(R.id.tv_chatRoomDesc);
+ mTv_search = (TextView) findViewById(R.id.tv_search);
+
+ mAc_iv_press_back = (LinearLayout) findViewById(R.id.ac_iv_press_back);
+ mSearchEditText = (EditText) findViewById(R.id.ac_et_search);
+ }
+
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchContactsActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchContactsActivity.java
index b8b975f6..408c4ccb 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/SearchContactsActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/SearchContactsActivity.java
@@ -1,5 +1,6 @@
package jiguang.chat.activity;
+import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -33,6 +34,8 @@
import android.widget.TextView;
import android.widget.Toast;
+import org.greenrobot.eventbus.EventBus;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -50,7 +53,6 @@
import cn.jpush.im.android.api.model.Message;
import cn.jpush.im.android.api.model.UserInfo;
import cn.jpush.im.android.api.options.MessageSendingOptions;
-import cn.jpush.im.android.eventbus.EventBus;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.application.JGApplication;
@@ -156,6 +158,7 @@ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
+ @SuppressLint("StaticFieldLeak")
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mFilterFriendList = new ArrayList<>();
@@ -175,14 +178,10 @@ protected SearchResult doInBackground(String... params) {
protected void onPostExecute(SearchResult searchResult) {
if (searchResult.getFilterStr().equals(mFilterString)) {
List friendList = searchResult.getFriendList();
- for (UserInfo friend : friendList) {
- mFilterFriendList.add(friend);
- }
+ mFilterFriendList.addAll(friendList);
List groupList = searchResult.getGroupList();
- for (GroupInfo group : groupList) {
- mFilterGroupList.add(group);
- }
+ mFilterGroupList.addAll(groupList);
if (mFilterFriendList.size() == 0 && mFilterGroupList.size() == 0) {
if (mFilterString.equals("")) {
diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchForChatRoomActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchForChatRoomActivity.java
new file mode 100644
index 00000000..04746eef
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/SearchForChatRoomActivity.java
@@ -0,0 +1,187 @@
+package jiguang.chat.activity;
+
+import android.content.Context;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.View;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import cn.jpush.im.android.api.ChatRoomManager;
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetUserInfoCallback;
+import cn.jpush.im.android.api.callback.RequestCallback;
+import cn.jpush.im.android.api.model.UserInfo;
+import cn.jpush.im.api.BasicCallback;
+import jiguang.chat.R;
+import jiguang.chat.application.JGApplication;
+import jiguang.chat.model.InfoModel;
+import jiguang.chat.utils.ToastUtil;
+import jiguang.chat.utils.dialog.LoadDialog;
+import jiguang.chat.utils.photochoose.SelectableRoundedImageView;
+
+public class SearchForChatRoomActivity extends BaseActivity implements View.OnClickListener {
+ private EditText mEtSearchUser;
+ private Button mBtnSearch;
+ private Button mSearchAddBtn;
+ private TextView mTvAddNot;
+ private LinearLayout mSearch_result;
+ private SelectableRoundedImageView mSearch_header;
+ private TextView mSearchName;
+ private ImageView mIvClear;
+ private long roomId;
+ private List keeperList = new ArrayList<>();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_search_for_chat_room);
+ roomId = getIntent().getLongExtra(JGApplication.ROOM_ID, 0);
+ mEtSearchUser = (EditText) findViewById(R.id.et_searchUser);
+ mEtSearchUser.addTextChangedListener(new TextChange());
+ mBtnSearch = (Button) findViewById(R.id.btn_search);
+ mBtnSearch.setOnClickListener(this);
+ mSearchAddBtn = (Button) findViewById(R.id.search_addBtn);
+ mSearchAddBtn.setOnClickListener(this);
+ mTvAddNot = (TextView) findViewById(R.id.search_addNot);
+ mSearch_result = (LinearLayout) findViewById(R.id.search_result);
+ mSearch_header = (SelectableRoundedImageView) findViewById(R.id.search_header);
+ mSearchName = (TextView) findViewById(R.id.search_name);
+ mIvClear = (ImageView) findViewById(R.id.iv_clear);
+ mIvClear.setOnClickListener(this);
+
+ initTitle(true, true, "添加管理员", "", false, "");
+ }
+
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.btn_search:
+ hintKbTwo();
+ String searchUserName = mEtSearchUser.getText().toString();
+ if (!TextUtils.isEmpty(searchUserName)) {
+ LoadDialog.show(this);
+ ChatRoomManager.getChatRoomAdminList(roomId, new RequestCallback>() {
+ @Override
+ public void gotResult(int responseCode, String responseMessage, List userInfos) {
+ if (responseCode == 0) {
+ keeperList.clear();
+ for (UserInfo userInfo : userInfos) {
+ keeperList.add(userInfo.getUserID());
+ }
+ }
+ JMessageClient.getUserInfo(searchUserName, new GetUserInfoCallback() {
+ @Override
+ public void gotResult(int responseCode, String responseMessage, UserInfo info) {
+ LoadDialog.dismiss(SearchForChatRoomActivity.this);
+ if (responseCode == 0) {
+ InfoModel.getInstance().friendInfo = info;
+ mSearch_result.setVisibility(View.VISIBLE);
+ //已经是管理员则不显示"添加"按钮
+ if (keeperList.contains(info.getUserID())) {
+ mSearchAddBtn.setVisibility(View.GONE);
+ mTvAddNot.setVisibility(View.VISIBLE);
+ mTvAddNot.setText("已添加");
+ } else {
+ mSearchAddBtn.setVisibility(View.VISIBLE);
+ mTvAddNot.setVisibility(View.GONE);
+ }
+ File avatarFile = info.getAvatarFile();
+ if (avatarFile != null) {
+ mSearch_header.setImageBitmap(BitmapFactory.decodeFile(avatarFile.getAbsolutePath()));
+ } else {
+ mSearch_header.setImageResource(R.drawable.rc_default_portrait);
+ }
+ mSearchName.setText(info.getDisplayName());
+ } else {
+ ToastUtil.shortToast(SearchForChatRoomActivity.this, "该用户不存在");
+ mSearch_result.setVisibility(View.GONE);
+ }
+ }
+ });
+ }
+ });
+ }
+ break;
+ case R.id.search_addBtn:
+ ChatRoomManager.addChatRoomAdmin(roomId, Collections.singletonList(InfoModel.getInstance().friendInfo), new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+ if (i == 0) {
+ ToastUtil.shortToast(SearchForChatRoomActivity.this, "添加成功");
+ } else {
+ handleErrorCode(i);
+ }
+
+ mSearch_result.setVisibility(View.GONE);
+ }
+ });
+ break;
+ case R.id.iv_clear:
+ mEtSearchUser.setText("");
+ break;
+ default:
+
+ }
+ }
+
+ private void handleErrorCode(int code) {
+ String result = "添加失败,code:" + code;
+ switch (code) {
+ case 7130004:
+ result = "添加失败,管理员人数已达上限";
+ break;
+ case 7130006:
+ result = "添加失败,用户不在聊天室中";
+ break;
+ default:
+ }
+ ToastUtil.shortToast(SearchForChatRoomActivity.this, result);
+ }
+
+ private class TextChange implements TextWatcher {
+
+ @Override
+ public void afterTextChanged(Editable arg0) {
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
+ int arg3) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence cs, int start, int before,
+ int count) {
+ boolean feedback = mEtSearchUser.getText().length() > 0;
+ if (feedback) {
+ mIvClear.setVisibility(View.VISIBLE);
+ mBtnSearch.setEnabled(true);
+ } else {
+ mIvClear.setVisibility(View.GONE);
+ mBtnSearch.setEnabled(false);
+ }
+ }
+ }
+
+ private void hintKbTwo() {
+ InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm.isActive() && getCurrentFocus() != null) {
+ if (getCurrentFocus().getWindowToken() != null) {
+ imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+ }
+ }
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchFriendDetailActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchFriendDetailActivity.java
index 49baa900..8aa62fcd 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/SearchFriendDetailActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/SearchFriendDetailActivity.java
@@ -10,6 +10,8 @@
import android.widget.ImageView;
import android.widget.TextView;
+import org.greenrobot.eventbus.EventBus;
+
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -18,7 +20,6 @@
import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback;
import cn.jpush.im.android.api.callback.GetUserInfoCallback;
import cn.jpush.im.android.api.model.UserInfo;
-import cn.jpush.im.android.eventbus.EventBus;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.application.JGApplication;
diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchGroupActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchGroupActivity.java
index 4889ffc2..d928dcef 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/SearchGroupActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/SearchGroupActivity.java
@@ -320,8 +320,14 @@ public void onItemClick(AdapterView> parent, View view, int position, long id)
UserInfo info = ((UserInfo) itemAtPosition);
if (info.isFriend()) {
intent.setClass(SearchGroupActivity.this, FriendInfoActivity.class);
+ if (getIntent().getFlags() == 1) {//设置是群成员点击过去的详情界面
+ intent.setFlags(1);
+ }
intent.putExtra("fromSearch", true);
} else {
+ if (getIntent().getFlags() == 1) {
+ intent.setFlags(1);
+ }
intent.setClass(SearchGroupActivity.this, GroupNotFriendActivity.class);
}
intent.putExtra(JGApplication.TARGET_ID, info.getUserName());
diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchMoreFriendsActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchMoreFriendsActivity.java
index e4cf868b..170f42be 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/SearchMoreFriendsActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/SearchMoreFriendsActivity.java
@@ -24,6 +24,8 @@
import android.widget.TextView;
import android.widget.Toast;
+import org.greenrobot.eventbus.EventBus;
+
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
@@ -38,7 +40,6 @@
import cn.jpush.im.android.api.model.Message;
import cn.jpush.im.android.api.model.UserInfo;
import cn.jpush.im.android.api.options.MessageSendingOptions;
-import cn.jpush.im.android.eventbus.EventBus;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.application.JGApplication;
diff --git a/chatapp/src/main/java/jiguang/chat/activity/SearchMoreGroupActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SearchMoreGroupActivity.java
index 1f28bdb6..cf6fae4c 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/SearchMoreGroupActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/SearchMoreGroupActivity.java
@@ -21,6 +21,8 @@
import android.widget.TextView;
import android.widget.Toast;
+import org.greenrobot.eventbus.EventBus;
+
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
@@ -34,7 +36,6 @@
import cn.jpush.im.android.api.model.Message;
import cn.jpush.im.android.api.model.UserInfo;
import cn.jpush.im.android.api.options.MessageSendingOptions;
-import cn.jpush.im.android.eventbus.EventBus;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.adapter.SearchGroupListAdapter;
diff --git a/chatapp/src/main/java/jiguang/chat/activity/SelectCreateGroupTypeActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SelectCreateGroupTypeActivity.java
new file mode 100644
index 00000000..9502d6f4
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/SelectCreateGroupTypeActivity.java
@@ -0,0 +1,265 @@
+package jiguang.chat.activity;
+
+import android.annotation.SuppressLint;
+import android.app.Dialog;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.io.File;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.CreateGroupCallback;
+import cn.jpush.im.android.api.model.Conversation;
+import cn.jpush.im.api.BasicCallback;
+import jiguang.chat.R;
+import jiguang.chat.application.JGApplication;
+import jiguang.chat.entity.Event;
+import jiguang.chat.entity.EventType;
+import jiguang.chat.utils.DialogCreator;
+import jiguang.chat.utils.ToastUtil;
+import jiguang.chat.utils.photochoose.ChoosePhoto;
+import jiguang.chat.utils.photochoose.PhotoUtils;
+
+/**
+ * Created by ${chenyn} on 2017/11/21.
+ */
+
+@SuppressLint("Registered")
+public class SelectCreateGroupTypeActivity extends BaseActivity implements TextWatcher {
+
+ private Dialog mLoadingDialog;
+ private ImageView mIv_groupAvatar;
+ private EditText mEt_groupName;
+ private LinearLayout mLl_groupType;
+ private TextView mTv_groupSelect;
+ private TextView tvInGroupDesc;
+ private Button mBtn_createGroup;
+ private ChoosePhoto mChoosePhoto;
+ private File avatarFile;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_select_create_group_type);
+ initTitle(true, true, "发起群聊", "", false, "");
+ JGApplication.groupAvatarPath = null;//清空头像信息
+
+ initView();
+ initData();
+ }
+
+ private void initData() {
+ mEt_groupName.addTextChangedListener(this);
+ mLl_groupType.setOnClickListener(v -> showDialog());
+ mBtn_createGroup.setOnClickListener(v -> {
+ mLoadingDialog = DialogCreator.createLoadingDialog(this, getString(R.string.creating_hint));
+ mLoadingDialog.show();
+ if (JGApplication.groupAvatarPath != null) {
+ avatarFile = new File(JGApplication.groupAvatarPath);
+ } else {
+ avatarFile = null;
+ }
+
+ if (mTv_groupSelect.getText().toString().equals("私有群")) {
+ //创建私有群
+ JMessageClient.createGroup(mEt_groupName.getText().toString(), "", avatarFile, "", new CreateGroupCallback() {
+ @Override
+ public void gotResult(int responseCode, String responseMsg, final long groupId) {
+ if (responseCode == 0) {
+ if (JGApplication.selectedUser.size() > 0) {
+ JMessageClient.addGroupMembers(groupId, JGApplication.selectedUser, new BasicCallback() {
+ @Override
+ public void gotResult(int responseCode, String responseMessage) {
+ mLoadingDialog.dismiss();
+ if (responseCode == 0) {
+ //如果创建群组时添加了人,那么就在size基础上加上自己
+ createGroup(groupId, JGApplication.selectedUser.size() + 1);
+ } else if (responseCode == 810007) {
+ ToastUtil.shortToast(SelectCreateGroupTypeActivity.this, "不能添加自己");
+ } else {
+ ToastUtil.shortToast(SelectCreateGroupTypeActivity.this, "添加失败");
+ }
+ }
+ });
+ } else {
+ mLoadingDialog.dismiss();
+ //如果创建群组时候没有选择人,那么size就是1
+ createGroup(groupId, 1);
+ }
+ Toast.makeText(SelectCreateGroupTypeActivity.this, "创建成功", Toast.LENGTH_SHORT).show();
+ } else {
+ mLoadingDialog.dismiss();
+ ToastUtil.shortToast(SelectCreateGroupTypeActivity.this, responseMsg);
+ }
+ }
+ });
+ } else {
+ JMessageClient.createPublicGroup(mEt_groupName.getText().toString(), "", avatarFile, "", new CreateGroupCallback() {
+ @Override
+ public void gotResult(int responseCode, String responseMsg, final long groupId) {
+ if (responseCode == 0) {
+ if (JGApplication.selectedUser.size() > 0) {
+ JMessageClient.addGroupMembers(groupId, JGApplication.selectedUser, new BasicCallback() {
+ @Override
+ public void gotResult(int responseCode, String responseMessage) {
+ mLoadingDialog.dismiss();
+ if (responseCode == 0) {
+ //如果创建群组时添加了人,那么就在size基础上加上自己
+ createGroup(groupId, JGApplication.selectedUser.size() + 1);
+ } else if (responseCode == 810007) {
+ ToastUtil.shortToast(SelectCreateGroupTypeActivity.this, "不能添加自己");
+ } else {
+ ToastUtil.shortToast(SelectCreateGroupTypeActivity.this, "添加失败");
+ }
+ }
+ });
+ } else {
+ mLoadingDialog.dismiss();
+ //如果创建群组时候没有选择人,那么size就是1
+ createGroup(groupId, 1);
+ }
+ Toast.makeText(SelectCreateGroupTypeActivity.this, "创建成功", Toast.LENGTH_SHORT).show();
+ } else {
+ mLoadingDialog.dismiss();
+ ToastUtil.shortToast(SelectCreateGroupTypeActivity.this, responseMsg);
+ }
+ }
+ });
+ }
+ });
+
+
+ mIv_groupAvatar.setOnClickListener(v -> {
+ mChoosePhoto = new ChoosePhoto();
+ mChoosePhoto.getCreateGroupAvatar(mIv_groupAvatar);
+ mChoosePhoto.showPhotoDialog(SelectCreateGroupTypeActivity.this);
+ });
+
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case PhotoUtils.INTENT_CROP:
+ case PhotoUtils.INTENT_TAKE:
+ case PhotoUtils.INTENT_SELECT:
+ mChoosePhoto.photoUtils.onActivityResult(SelectCreateGroupTypeActivity.this, requestCode, resultCode, data);
+ break;
+ }
+ }
+
+ private void createGroup(long groupId, int groupMembersSize) {
+ Conversation groupConversation = JMessageClient.getGroupConversation(groupId);
+ if (groupConversation == null) {
+ groupConversation = Conversation.createGroupConversation(groupId);
+ EventBus.getDefault().post(new Event.Builder()
+ .setType(EventType.createConversation)
+ .setConversation(groupConversation)
+ .build());
+ }
+
+ Intent intent = new Intent();
+ //设置跳转标志
+ intent.putExtra("fromGroup", true);
+ intent.putExtra(JGApplication.CONV_TITLE, groupConversation.getTitle());
+ intent.putExtra(JGApplication.MEMBERS_COUNT, groupMembersSize);
+ intent.putExtra(JGApplication.GROUP_ID, groupId);
+ intent.setClass(SelectCreateGroupTypeActivity.this, ChatActivity.class);
+ startActivity(intent);
+ finish();
+ }
+
+ private void initView() {
+ mIv_groupAvatar = (ImageView) findViewById(R.id.iv_groupAvatar);
+ mEt_groupName = (EditText) findViewById(R.id.et_groupName);
+ mLl_groupType = (LinearLayout) findViewById(R.id.ll_groupType);
+ mTv_groupSelect = (TextView) findViewById(R.id.tv_groupSelect);
+ tvInGroupDesc = (TextView) findViewById(R.id.tvInGroupDesc);
+ mBtn_createGroup = (Button) findViewById(R.id.btn_createGroup);
+
+ mBtn_createGroup.setClickable(false);
+ mBtn_createGroup.setEnabled(false);
+ }
+
+
+ public void showDialog() {
+ final Dialog genderDialog = new Dialog(this, R.style.jmui_default_dialog_style);
+ LayoutInflater inflater = LayoutInflater.from(this);
+ View view = inflater.inflate(R.layout.dialog_set_sex, null);
+ genderDialog.setContentView(view);
+ Window window = genderDialog.getWindow();
+ window.setWindowAnimations(R.style.mystyle); // 添加动画
+ window.setGravity(Gravity.BOTTOM);
+ window.setLayout(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ genderDialog.show();
+ genderDialog.setCanceledOnTouchOutside(true);
+ Button man = (Button) view.findViewById(R.id.man_rl);
+ Button woman = (Button) view.findViewById(R.id.woman_rl);
+ Button secrecy = (Button) view.findViewById(R.id.rl_secrecy);
+ man.setText("私有群");
+ woman.setText("公开群");
+ secrecy.setText("取消");
+
+ View.OnClickListener listener = v -> {
+ switch (v.getId()) {
+ case R.id.man_rl:
+ mTv_groupSelect.setText("私有群");
+ tvInGroupDesc.setText("只能通过群成员邀请入群,无需审核");
+ genderDialog.dismiss();
+ break;
+ case R.id.woman_rl:
+ mTv_groupSelect.setText("公开群");
+ tvInGroupDesc.setText("用户可主动申请入群,需群主审核");
+ genderDialog.dismiss();
+ break;
+ case R.id.rl_secrecy:
+ genderDialog.dismiss();
+ break;
+
+ }
+ };
+ man.setOnClickListener(listener);
+ woman.setOnClickListener(listener);
+ secrecy.setOnClickListener(listener);
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ String inputString = mEt_groupName.getText().toString();
+ if (TextUtils.isEmpty(inputString)) {
+ mBtn_createGroup.setEnabled(false);
+ mBtn_createGroup.setClickable(false);
+ mBtn_createGroup.setBackgroundColor(Color.parseColor("#81E3E2"));
+ } else {
+ mBtn_createGroup.setClickable(true);
+ mBtn_createGroup.setEnabled(true);
+ mBtn_createGroup.setBackgroundColor(Color.parseColor("#2DD0CF"));
+ }
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/SetGroupSilenceActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SetGroupSilenceActivity.java
new file mode 100644
index 00000000..658847bf
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/SetGroupSilenceActivity.java
@@ -0,0 +1,65 @@
+package jiguang.chat.activity;
+
+import android.app.Dialog;
+import android.os.Bundle;
+import android.widget.Switch;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetGroupInfoCallback;
+import cn.jpush.im.android.api.model.GroupInfo;
+import cn.jpush.im.api.BasicCallback;
+import jiguang.chat.R;
+import jiguang.chat.utils.DialogCreator;
+import jiguang.chat.utils.ToastUtil;
+
+/**
+ * Created by ${chenyn} on 2017/11/27.
+ */
+
+public class SetGroupSilenceActivity extends BaseActivity {
+ private GroupInfo mGroupInfo;
+ private String mUserName;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_set_group_silence);
+ initTitle(true, true, "设置", "", false, "");
+
+ Switch switchButton = (Switch) findViewById(R.id.switchButton);
+ Dialog loadingDialog = DialogCreator.createLoadingDialog(SetGroupSilenceActivity.this, "正在加载...");
+ loadingDialog.show();
+
+ long groupID = getIntent().getLongExtra("groupID", 0);
+ mUserName = getIntent().getStringExtra("userName");
+
+ JMessageClient.getGroupInfo(groupID, new GetGroupInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, GroupInfo groupInfo) {
+ if (i == 0) {
+ mGroupInfo = groupInfo;
+ switchButton.setChecked(groupInfo.isKeepSilence(mUserName, JMessageClient.getMyInfo().getAppKey()));
+ }
+ loadingDialog.dismiss();
+ }
+ });
+
+ switchButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
+ //如果是手动设置才走下面.
+ if (switchButton.isPressed()) {
+ mGroupInfo.setGroupMemSilence(mUserName, JMessageClient.getMyInfo().getAppKey(), isChecked, new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+ if (i == 0) {
+ ToastUtil.shortToast(SetGroupSilenceActivity.this, "设置成功");
+ } else {
+ ToastUtil.shortToast(SetGroupSilenceActivity.this, "设置失败" + i + s);
+ }
+ }
+ });
+ }
+ });
+
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/SilenceUsersActivity.java b/chatapp/src/main/java/jiguang/chat/activity/SilenceUsersActivity.java
new file mode 100644
index 00000000..512404f1
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/SilenceUsersActivity.java
@@ -0,0 +1,168 @@
+package jiguang.chat.activity;
+
+import android.app.Dialog;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.File;
+import java.util.List;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback;
+import cn.jpush.im.android.api.callback.GetGroupInfoCallback;
+import cn.jpush.im.android.api.model.GroupInfo;
+import cn.jpush.im.android.api.model.UserInfo;
+import cn.jpush.im.api.BasicCallback;
+import jiguang.chat.R;
+import jiguang.chat.utils.DialogCreator;
+
+/**
+ * Created by ${chenyn} on 2017/11/28.
+ */
+
+public class SilenceUsersActivity extends BaseActivity {
+
+ private ListView mLv_silenceUsers;
+ private List mSilenceMembers;
+ private String mGroupOwner;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_silence_users);
+
+ initView();
+ initData();
+ }
+
+ private void initView() {
+ initTitle(true, true, "群禁言列表", "", false, "");
+ mLv_silenceUsers = (ListView) findViewById(R.id.lv_silenceUsers);
+ }
+
+ private void initData() {
+ long groupID = getIntent().getLongExtra("groupID", 0);
+ Dialog loadingDialog = DialogCreator.createLoadingDialog(SilenceUsersActivity.this, "正在加载...");
+ loadingDialog.show();
+ JMessageClient.getGroupInfo(groupID, new GetGroupInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, GroupInfo groupInfo) {
+ loadingDialog.dismiss();
+ if (i == 0) {
+ mGroupOwner = groupInfo.getGroupOwner();
+ mSilenceMembers = groupInfo.getGroupSilenceMembers();
+ mLv_silenceUsers.setAdapter(new SilenceMembersAdapter(groupInfo));
+ } else {
+ Toast.makeText(SilenceUsersActivity.this, "没有禁言列表", Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+
+ mLv_silenceUsers.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ UserInfo userInfo = (UserInfo) parent.getItemAtPosition(position);
+ Intent intent = new Intent(SilenceUsersActivity.this, GroupUserInfoActivity.class);
+ intent.putExtra("groupID", groupID);
+ intent.putExtra("groupUserName", userInfo.getUserName());
+ intent.putExtra("groupOwner", mGroupOwner);
+ startActivity(intent);
+ }
+ });
+ }
+
+ class SilenceMembersAdapter extends BaseAdapter {
+ private GroupInfo mGroupInfo;
+
+ public SilenceMembersAdapter(GroupInfo groupInfo) {
+ this.mGroupInfo = groupInfo;
+ }
+
+ @Override
+ public int getCount() {
+ return mSilenceMembers == null ? 0 : mSilenceMembers.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mSilenceMembers.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ UserInfo userInfo = mSilenceMembers.get(position);
+ ViewHolder holder;
+ if (convertView == null) {
+ holder = new ViewHolder();
+ convertView = View.inflate(SilenceUsersActivity.this, R.layout.item_silence_member, null);
+ holder.iv_userAvatar = convertView.findViewById(R.id.iv_userAvatar);
+ holder.tv_userName = convertView.findViewById(R.id.tv_userName);
+ holder.tv_delSilence = convertView.findViewById(R.id.tv_delSilence);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ String groupOwner = mGroupInfo.getGroupOwner();
+ if (groupOwner.equals(JMessageClient.getMyInfo().getUserName())) {
+ holder.tv_delSilence.setVisibility(View.VISIBLE);
+ } else {
+ holder.tv_delSilence.setVisibility(View.GONE);
+ }
+
+ File avatarFile = userInfo.getAvatarFile();
+ if (avatarFile == null) {
+ userInfo.getBigAvatarBitmap(new GetAvatarBitmapCallback() {
+ @Override
+ public void gotResult(int i, String s, Bitmap bitmap) {
+ if (i == 0) {
+ holder.iv_userAvatar.setImageBitmap(bitmap);
+ } else {
+ holder.iv_userAvatar.setImageResource(R.drawable.jmui_head_icon);
+ }
+ }
+ });
+ } else {
+ holder.iv_userAvatar.setImageBitmap(BitmapFactory.decodeFile(avatarFile.getPath()));
+ }
+
+ holder.tv_userName.setText(userInfo.getDisplayName());
+ holder.tv_delSilence.setOnClickListener(v -> mGroupInfo.setGroupMemSilence(userInfo.getUserName(), userInfo.getAppKey(), false, new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+ if (i == 0) {
+ Toast.makeText(SilenceUsersActivity.this, "取消成功", Toast.LENGTH_SHORT).show();
+ mSilenceMembers.remove(userInfo);
+ } else {
+ Toast.makeText(SilenceUsersActivity.this, "取消失败", Toast.LENGTH_SHORT).show();
+ }
+ notifyDataSetChanged();
+ }
+ }));
+
+ return convertView;
+ }
+
+ class ViewHolder {
+ ImageView iv_userAvatar;
+ TextView tv_userName;
+ TextView tv_delSilence;
+ }
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/VerificationActivity.java b/chatapp/src/main/java/jiguang/chat/activity/VerificationActivity.java
index 608b5c23..32a649ab 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/VerificationActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/VerificationActivity.java
@@ -3,11 +3,8 @@
import android.app.Dialog;
import android.os.Bundle;
import android.text.TextUtils;
-import android.view.KeyEvent;
-import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
-import android.widget.TextView;
import cn.jpush.im.android.api.ContactManager;
import cn.jpush.im.android.api.JMessageClient;
@@ -42,22 +39,14 @@ protected void onCreate(Bundle savedInstanceState) {
}
private void initData() {
- mEt_reason.setOnEditorActionListener(new TextView.OnEditorActionListener() {
- @Override
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (actionId == EditorInfo.IME_ACTION_SEND) {
- sendAddReason();
- }
- return false;
- }
- });
-
- mJmui_commit_btn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
+ mEt_reason.setOnEditorActionListener((v, actionId, event) -> {
+ if (actionId == EditorInfo.IME_ACTION_SEND) {
sendAddReason();
}
+ return false;
});
+
+ mJmui_commit_btn.setOnClickListener(v -> sendAddReason());
}
private void sendAddReason() {
diff --git a/chatapp/src/main/java/jiguang/chat/activity/VerificationGroupActivity.java b/chatapp/src/main/java/jiguang/chat/activity/VerificationGroupActivity.java
new file mode 100644
index 00000000..9b22fe74
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/VerificationGroupActivity.java
@@ -0,0 +1,54 @@
+package jiguang.chat.activity;
+
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.api.BasicCallback;
+import jiguang.chat.R;
+import jiguang.chat.utils.HandleResponseCode;
+
+/**
+ * Created by ${chenyn} on 2017/11/6.
+ */
+
+public class VerificationGroupActivity extends BaseActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.activity_verification);
+ initTitle(true, true, "验证信息", "", true, "发送");
+ EditText et_reason = (EditText) findViewById(R.id.et_reason);
+ et_reason.setHint("请填写验证信息");
+
+ mJmui_commit_btn.setOnClickListener(v -> {
+ //发送加入群组验证信息
+ String verification = "";
+ if (!TextUtils.isEmpty(et_reason.getText())) {
+ verification = et_reason.getText().toString();
+ }
+
+ long openGroupID = getIntent().getLongExtra("openGroupID", 0);
+
+ JMessageClient.applyJoinGroup(openGroupID, verification, new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+ if (i == 0) {
+ Toast.makeText(VerificationGroupActivity.this, "申请已发出,等待审核", Toast.LENGTH_SHORT).show();
+ finish();
+ } else {
+ HandleResponseCode.onHandle(VerificationGroupActivity.this, i, false);
+ }
+ }
+ });
+
+
+ });
+
+
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/VerificationMessageActivity.java b/chatapp/src/main/java/jiguang/chat/activity/VerificationMessageActivity.java
new file mode 100644
index 00000000..c3d4d8e9
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/VerificationMessageActivity.java
@@ -0,0 +1,66 @@
+package jiguang.chat.activity;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.widget.ImageButton;
+import android.widget.RadioGroup;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jiguang.chat.R;
+import jiguang.chat.activity.fragment.FriendFragment;
+import jiguang.chat.activity.fragment.GroupFragment;
+import jiguang.chat.adapter.ViewPagerAdapter;
+import jiguang.chat.view.NoScrollViewPager;
+
+/**
+ * Created by ${chenyn} on 2017/11/7.
+ */
+
+public class VerificationMessageActivity extends FragmentActivity {
+
+ private NoScrollViewPager mPager;
+ private List mFragmentList;
+ private RadioGroup mRg;
+ private int mCurTabIndex;
+ private ImageButton mReturn_btn;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_verification_message);
+ initData();
+ }
+
+ private void initData() {
+ mPager = findViewById(R.id.verification_viewpager);
+ mRg = findViewById(R.id.rg_verification);
+ mReturn_btn = findViewById(R.id.return_btn);
+
+ mFragmentList = new ArrayList<>();
+ mFragmentList.add(new FriendFragment());
+ mFragmentList.add(new GroupFragment());
+ mRg.check(R.id.rb_friend);
+
+ mPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager(), mFragmentList));
+
+ mRg.setOnCheckedChangeListener((group, checkedId) -> {
+ switch (checkedId) {
+ case R.id.rb_friend:
+ mCurTabIndex = 0;
+ break;
+ case R.id.rb_group:
+ mCurTabIndex = 1;
+ break;
+ default:
+ break;
+ }
+ mPager.setCurrentItem(mCurTabIndex, false);
+ });
+
+ mReturn_btn.setOnClickListener(v -> finish());
+ }
+
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/fragment/BaseFragment.java b/chatapp/src/main/java/jiguang/chat/activity/fragment/BaseFragment.java
index 476192f2..39baf066 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/fragment/BaseFragment.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/fragment/BaseFragment.java
@@ -39,6 +39,7 @@ public class BaseFragment extends Fragment {
protected int mAvatarSize;
private Context mContext;
public Activity mActivity;
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/chatapp/src/main/java/jiguang/chat/activity/fragment/ChatRoomFragment.java b/chatapp/src/main/java/jiguang/chat/activity/fragment/ChatRoomFragment.java
new file mode 100644
index 00000000..ecdcdcbd
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/fragment/ChatRoomFragment.java
@@ -0,0 +1,49 @@
+package jiguang.chat.activity.fragment;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import jiguang.chat.R;
+import jiguang.chat.controller.ChatRoomController;
+import jiguang.chat.view.ChatRoomView;
+
+/**
+ * Created by ${chenyn} on 2017/10/31.
+ */
+
+public class ChatRoomFragment extends BaseFragment {
+ private Context mContext;
+ private View mRootView;
+ private ChatRoomView mChatRoomView;
+ private ChatRoomController mRoomController;
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mContext = this.getActivity();
+ LayoutInflater layoutInflater = getActivity().getLayoutInflater();
+ mRootView = layoutInflater.inflate(R.layout.fragment_chat_room,
+ getActivity().findViewById(R.id.main_view), false);
+
+ mChatRoomView = mRootView.findViewById(R.id.chat_room_view);
+ mChatRoomView.initModule();
+ mRoomController = new ChatRoomController(mChatRoomView, mContext);
+
+ mChatRoomView.setListener(mRoomController);
+ mChatRoomView.setClickListener(mRoomController);
+ mChatRoomView.setOnRefreshListener(mRoomController);
+ mChatRoomView.setOnLoadMoreListener(mRoomController);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ ViewGroup p = (ViewGroup) mRootView.getParent();
+ if (p != null) {
+ p.removeAllViewsInLayout();
+ }
+ return mRootView;
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/fragment/ContactsFragment.java b/chatapp/src/main/java/jiguang/chat/activity/fragment/ContactsFragment.java
index 9d1246ee..1760dab0 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/fragment/ContactsFragment.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/fragment/ContactsFragment.java
@@ -6,6 +6,11 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.google.gson.Gson;
+
+import org.greenrobot.eventbus.EventBus;
import java.util.ArrayList;
import java.util.List;
@@ -17,19 +22,23 @@
import cn.jpush.im.android.api.callback.GetUserInfoCallback;
import cn.jpush.im.android.api.callback.GetUserInfoListCallback;
import cn.jpush.im.android.api.event.ContactNotifyEvent;
+import cn.jpush.im.android.api.event.GroupApprovalEvent;
+import cn.jpush.im.android.api.event.GroupApprovalRefuseEvent;
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.GroupInfo;
import cn.jpush.im.android.api.model.UserInfo;
-import cn.jpush.im.android.eventbus.EventBus;
import jiguang.chat.R;
import jiguang.chat.application.JGApplication;
import jiguang.chat.controller.ContactsController;
import jiguang.chat.database.FriendEntry;
import jiguang.chat.database.FriendRecommendEntry;
+import jiguang.chat.database.GroupApplyEntry;
+import jiguang.chat.database.RefuseGroupEntry;
import jiguang.chat.database.UserEntry;
import jiguang.chat.entity.Event;
import jiguang.chat.entity.EventType;
import jiguang.chat.entity.FriendInvitation;
+import jiguang.chat.entity.GroupApplyInvitation;
import jiguang.chat.utils.SharePreferenceManager;
import jiguang.chat.utils.ThreadUtil;
import jiguang.chat.utils.pinyin.HanziToPinyin;
@@ -42,10 +51,10 @@
public class ContactsFragment extends BaseFragment {
private View mRootView;
private ContactsView mContactsView;
+ private TextView mAllContactNumber;
private ContactsController mContactsController;
private Activity mContext;
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -56,6 +65,7 @@ public void onCreate(Bundle savedInstanceState) {
(ViewGroup) getActivity().findViewById(R.id.main_view), false);
mContactsView = (ContactsView) mRootView.findViewById(R.id.contacts_view);
+ mAllContactNumber = getActivity().findViewById(R.id.all_contact_number);
mContactsView.initModule(mRatio, mDensity);
mContactsController = new ContactsController(mContactsView, this.getActivity());
@@ -210,6 +220,8 @@ public void gotResult(int status, String desc, UserInfo userInfo) {
//收到好友请求数字 +1
int showNum = SharePreferenceManager.getCachedNewFriendNum() + 1;
mContactsView.showNewFriends(showNum);
+ mAllContactNumber.setVisibility(View.VISIBLE);
+ mAllContactNumber.setText(String.valueOf(showNum));
SharePreferenceManager.setCachedNewFriendNum(showNum);
}
}
@@ -239,6 +251,109 @@ public void onEventMainThread(Event event) {
}
}
+ //群主收到群组验证事件
+ public void onEvent(GroupApprovalEvent event) {
+ final UserEntry user = JGApplication.getUserEntry();
+ GroupApprovalEvent.Type type = event.getType();
+ long gid = event.getGid();
+ event.getFromUserInfo(new GetUserInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, UserInfo fromUserInfo) {
+ if (i == 0) {
+ Gson gson = new Gson();
+ event.getApprovalUserInfoList(new GetUserInfoListCallback() {
+ @Override
+ public void gotResult(int i, String s, List list) {
+ if (i == 0) {
+ if (JGApplication.forAddIntoGroup.size() > 0) {
+ for (String addName : JGApplication.forAddIntoGroup) {
+ if (addName.equals(list.get(0).getUserName())) {
+ return;
+ } else {
+ JGApplication.forAddIntoGroup.add(list.get(0).getUserName());
+ }
+ }
+ }
+ GroupApplyEntry entry;
+ //邀请,from是邀请方
+ if (type.equals(GroupApprovalEvent.Type.invited_into_group)) {
+ entry = GroupApplyEntry.getEntry(user, list.get(0).getUserName(), list.get(0).getAppKey());
+ if (entry != null) {
+ entry.delete();
+ }
+ if (fromUserInfo.getAvatar() != null) {
+ entry = new GroupApplyEntry(fromUserInfo.getUserName(), list.get(0).getUserName(), fromUserInfo.getAppKey(),
+ list.get(0).getAvatarFile().getPath(), fromUserInfo.getDisplayName(), list.get(0).getDisplayName(),
+ null, GroupApplyInvitation.INVITED.getValue(), gson.toJson(event), gid + "",
+ user, 0, 0);//邀请type=0
+ } else {
+ entry = new GroupApplyEntry(fromUserInfo.getUserName(), list.get(0).getUserName(), fromUserInfo.getAppKey(),
+ null, fromUserInfo.getDisplayName(), list.get(0).getDisplayName(),
+ null, GroupApplyInvitation.INVITED.getValue(), gson.toJson(event), gid + "",
+ user, 0, 0);//邀请type=0
+ }
+ } else {
+ entry = GroupApplyEntry.getEntry(user, fromUserInfo.getUserName(), fromUserInfo.getAppKey());
+ if (entry != null) {
+ entry.delete();
+ }
+ if (fromUserInfo.getAvatar() != null) {
+ entry = new GroupApplyEntry(list.get(0).getUserName(), list.get(0).getUserName(), list.get(0).getAppKey(),
+ list.get(0).getAvatarFile().getPath(), list.get(0).getDisplayName(), list.get(0).getDisplayName(),
+ event.getReason(), GroupApplyInvitation.INVITED.getValue(), gson.toJson(event), gid + "",
+ user, 0, 1);//申请type=1
+ } else {
+ entry = new GroupApplyEntry(list.get(0).getUserName(), list.get(0).getUserName(), list.get(0).getAppKey(),
+ null, fromUserInfo.getDisplayName(), list.get(0).getDisplayName(),
+ event.getReason(), GroupApplyInvitation.INVITED.getValue(), gson.toJson(event), gid + "",
+ user, 0, 1);//申请type=1
+ }
+ }
+ entry.save();
+
+ int showNum = SharePreferenceManager.getCachedNewFriendNum() + 1;
+ mContactsView.showNewFriends(showNum);
+ mAllContactNumber.setVisibility(View.VISIBLE);
+ mAllContactNumber.setText(String.valueOf(showNum));
+
+ SharePreferenceManager.setCachedNewFriendNum(showNum);
+ }
+ }
+ });
+
+ }
+ }
+ });
+ }
+
+ //收到被拒绝事件
+ public void onEvent(GroupApprovalRefuseEvent event) {
+ final UserEntry user = JGApplication.getUserEntry();
+ long gid = event.getGid();
+ event.getToUserInfoList(new GetUserInfoListCallback() {
+ @Override
+ public void gotResult(int i, String s, List list) {
+ if (i == 0) {
+ String userName = list.get(0).getUserName();
+ String displayName = list.get(0).getDisplayName();
+ String appKey = list.get(0).getAppKey();
+ String path = null;
+ if (list.get(0).getAvatar() != null) {
+ path = list.get(0).getAvatarFile().getPath();
+ }
+ RefuseGroupEntry groupEntry = RefuseGroupEntry.getEntry(user, userName, appKey);
+ if (groupEntry != null) {
+ groupEntry.delete();
+ }
+ groupEntry = new RefuseGroupEntry(user, userName, displayName, gid + "", appKey, path);
+ groupEntry.save();
+
+ }
+ }
+ });
+
+ }
+
private String getLetter(String name) {
String letter;
ArrayList tokens = HanziToPinyin.getInstance()
diff --git a/chatapp/src/main/java/jiguang/chat/activity/fragment/ConversationListFragment.java b/chatapp/src/main/java/jiguang/chat/activity/fragment/ConversationListFragment.java
index c6abc91a..18d3ed51 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/fragment/ConversationListFragment.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/fragment/ConversationListFragment.java
@@ -20,6 +20,10 @@
import android.view.WindowManager;
import android.widget.PopupWindow;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
+
import cn.jpush.im.android.api.JMessageClient;
import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback;
import cn.jpush.im.android.api.enums.ConversationType;
@@ -32,7 +36,6 @@
import cn.jpush.im.android.api.model.GroupInfo;
import cn.jpush.im.android.api.model.Message;
import cn.jpush.im.android.api.model.UserInfo;
-import cn.jpush.im.android.eventbus.EventBus;
import jiguang.chat.R;
import jiguang.chat.application.JGApplication;
import jiguang.chat.controller.ConversationListController;
@@ -67,6 +70,9 @@ public class ConversationListFragment extends BaseFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (!EventBus.getDefault().isRegistered(this)) {
+ EventBus.getDefault().register(this);
+ }
isCreate = true;
mContext = this.getActivity();
@@ -199,7 +205,7 @@ public void gotResult(int responseCode, String responseMessage, Bitmap avatarBit
*/
public void onEvent(OfflineMessageEvent event) {
Conversation conv = event.getConversation();
- if (!conv.getTargetId().equals("feedback_Android")) {
+ if (!conv.getTargetId().equals("feedback_Android") && conv.getType() != ConversationType.chatroom) {
mBackgroundHandler.sendMessage(mBackgroundHandler.obtainMessage(REFRESH_CONVERSATION_LIST, conv));
}
}
@@ -226,7 +232,7 @@ public void onEventMainThread(MessageReceiptStatusChangeEvent event) {
*/
public void onEvent(ConversationRefreshEvent event) {
Conversation conv = event.getConversation();
- if (!conv.getTargetId().equals("feedback_Android")) {
+ if (!conv.getTargetId().equals("feedback_Android") && conv.getType() != ConversationType.chatroom) {
mBackgroundHandler.sendMessage(mBackgroundHandler.obtainMessage(REFRESH_CONVERSATION_LIST, conv));
//多端在线未读数改变时刷新
if (event.getReason().equals(ConversationRefreshEvent.Reason.UNREAD_CNT_UPDATED)) {
@@ -246,7 +252,9 @@ public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case REFRESH_CONVERSATION_LIST:
Conversation conv = (Conversation) msg.obj;
- mConvListController.getAdapter().setToTop(conv);
+ if (conv.getType() != ConversationType.chatroom) {
+ mConvListController.getAdapter().setToTop(conv);
+ }
break;
case DISMISS_REFRESH_HEADER:
mContext.runOnUiThread(new Runnable() {
@@ -264,7 +272,8 @@ public void run() {
}
}
- public void onEventMainThread(Event event) {
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void onEvent(Event event) { ;
switch (event.getType()) {
case createConversation:
Conversation conv = event.getConversation();
@@ -311,6 +320,9 @@ public void onResume() {
super.onResume();
dismissPopWindow();
mMenuItemView.showAddFriend();
+ if (JGApplication.delConversation != null) {
+ mConvListController.delConversation();
+ }
mConvListController.getAdapter().notifyDataSetChanged();
}
@@ -334,5 +346,4 @@ public void sortConvList() {
mConvListController.getAdapter().sortConvList();
}
}
-
}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/FriendRecommendActivity.java b/chatapp/src/main/java/jiguang/chat/activity/fragment/FriendFragment.java
similarity index 62%
rename from chatapp/src/main/java/jiguang/chat/activity/FriendRecommendActivity.java
rename to chatapp/src/main/java/jiguang/chat/activity/fragment/FriendFragment.java
index 2d256082..8251d2ef 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/FriendRecommendActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/fragment/FriendFragment.java
@@ -1,8 +1,13 @@
-package jiguang.chat.activity;
+package jiguang.chat.activity.fragment;
+import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
import android.widget.ListView;
import java.util.List;
@@ -15,24 +20,23 @@
import jiguang.chat.entity.FriendInvitation;
/**
- * Created by ${chenyn} on 2017/3/17.
- *
- * 通讯录界面.验证消息
+ * Created by ${chenyn} on 2017/11/7.
*/
-public class FriendRecommendActivity extends BaseActivity {
+public class FriendFragment extends BaseFragment {
+ private Activity mContext;
private ListView mListView;
private FriendRecommendAdapter mAdapter;
private List mList;
@Override
- protected void onCreate(Bundle savedInstanceState) {
+ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_friend_recommend);
-
- initView();
+ this.mContext = getActivity();
+ }
+ private void initData() {
UserEntry user = JGApplication.getUserEntry();
if (null != user) {
mList = user.getRecommends();
@@ -43,14 +47,21 @@ protected void onCreate(Bundle savedInstanceState) {
}
}
- private void initView() {
- initTitle(true, true, "新的朋友", "", false, "");
- mListView = (ListView) findViewById(R.id.friend_recommend_list_view);
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ return initView();
+ }
+ private View initView() {
+ View view = View.inflate(mContext, R.layout.verification_friend, null);
+ mListView = view.findViewById(R.id.friend_recommend_list_view);
+ initData();
+ return view;
}
@Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (resultCode) {
case JGApplication.RESULT_BUTTON:
@@ -60,7 +71,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (btnState == 2) {
entry.state = FriendInvitation.ACCEPTED.getValue();
entry.save();
- }else if (btnState == 1) {
+ } else if (btnState == 1) {
entry.state = FriendInvitation.REFUSED.getValue();
entry.save();
}
@@ -70,7 +81,9 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
}
}
- protected void onResume() {
+
+ @Override
+ public void onResume() {
super.onResume();
mAdapter.notifyDataSetChanged();
}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/fragment/GroupFragment.java b/chatapp/src/main/java/jiguang/chat/activity/fragment/GroupFragment.java
new file mode 100644
index 00000000..17c82331
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/activity/fragment/GroupFragment.java
@@ -0,0 +1,175 @@
+package jiguang.chat.activity.fragment;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.List;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetGroupInfoCallback;
+import cn.jpush.im.android.api.model.GroupInfo;
+import jiguang.chat.R;
+import jiguang.chat.activity.ApplyGroupInfoActivity;
+import jiguang.chat.activity.GroupInfoActivity;
+import jiguang.chat.adapter.GroupVerificationAdapter;
+import jiguang.chat.application.JGApplication;
+import jiguang.chat.database.GroupApplyEntry;
+import jiguang.chat.database.RefuseGroupEntry;
+import jiguang.chat.database.UserEntry;
+
+/**
+ * Created by ${chenyn} on 2017/11/7.
+ */
+
+public class GroupFragment extends BaseFragment {
+ private Activity mContext;
+ private ListView mListView;
+ private List mRecommends;
+ private GroupVerificationAdapter mAdapter;
+ private List mRefuseGroupEntryList;
+ private LayoutInflater mInflater;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ this.mContext = getActivity();
+ }
+
+ private void initData() {
+ UserEntry user = JGApplication.getUserEntry();
+ if (user != null) {
+ mRecommends = user.getGroupApplyRecommends();
+ mAdapter = new GroupVerificationAdapter(mContext, mRecommends);
+ mListView.setAdapter(mAdapter);
+
+ mRefuseGroupEntryList = user.getRefuseGroupRecommends();
+ if (mRefuseGroupEntryList != null && mRefuseGroupEntryList.size() > 0) {
+ mListView.setAdapter(new RefuseGroupAdapter());
+ }
+ }
+
+ //点击事件要分类型
+ mListView.setOnItemClickListener((parent, view, position, id) -> {
+ Intent intent = new Intent();
+ Object itemAtPosition = parent.getItemAtPosition(position);
+ if (itemAtPosition instanceof GroupApplyEntry) {
+ intent.setClass(mContext, ApplyGroupInfoActivity.class);
+ GroupApplyEntry entry = (GroupApplyEntry) itemAtPosition;
+ intent.putExtra("toName", entry.toUsername);
+ intent.putExtra("reason", entry.reason);
+ startActivity(intent);
+ }else {
+ intent.setClass(mContext, GroupInfoActivity.class);
+ RefuseGroupEntry entry = (RefuseGroupEntry) itemAtPosition;
+ intent.setFlags(1);
+ intent.putExtra("groupId", entry.groupId);
+ startActivity(intent);
+ }
+ });
+
+ mListView.setOnItemLongClickListener((parent, view, position, id) -> {
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+ builder.setTitle("是否删除?").setPositiveButton("确定", (dialog, which) -> {
+
+ GroupApplyEntry entry = (GroupApplyEntry) parent.getItemAtPosition(position);
+ entry.delete();
+ mRecommends.remove(entry);
+ mAdapter.notifyDataSetChanged();
+
+ }).setNegativeButton("取消", (dialog, which) -> {
+ }).show();
+
+ return true;
+ });
+ }
+
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ mInflater = LayoutInflater.from(mContext);
+ return initView();
+ }
+
+ private View initView() {
+ View view = View.inflate(mContext, R.layout.verification_group, null);
+ mListView = view.findViewById(R.id.group_recommend_list_view);
+ initData();
+ return view;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mAdapter.notifyDataSetChanged();
+ }
+
+ class RefuseGroupAdapter extends BaseAdapter {
+
+ @Override
+ public int getCount() {
+ return mRefuseGroupEntryList.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mRefuseGroupEntryList.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ RefuseGroupEntry entry = mRefuseGroupEntryList.get(position);
+
+ ViewHolder holder;
+ if (convertView == null) {
+ holder = new ViewHolder();
+ convertView = mInflater.inflate(R.layout.item_refuse_group, null);
+ holder.groupAvatar = convertView.findViewById(R.id.groupAvatar);
+ holder.groupName = convertView.findViewById(R.id.groupName);
+ holder.refuseJoin = convertView.findViewById(R.id.refuseJoin);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ holder.refuseJoin.setText("群主拒绝 " + entry.displayName + " 入群");
+ JMessageClient.getGroupInfo(Long.parseLong(entry.groupId), new GetGroupInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, GroupInfo groupInfo) {
+ if (i == 0) {
+ holder.groupName.setText(groupInfo.getGroupName());
+ if (groupInfo.getAvatar() != null) {
+ holder.groupAvatar.setImageBitmap(BitmapFactory.decodeFile(groupInfo.getAvatarFile().getPath()));
+ } else {
+ holder.groupAvatar.setImageResource(R.drawable.group);
+ }
+ }
+ }
+ });
+ return convertView;
+ }
+
+ class ViewHolder {
+ ImageView groupAvatar;
+ TextView groupName;
+ TextView refuseJoin;
+ }
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/AudioFileAdapter.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/AudioFileAdapter.java
index 0903b09c..68b94a76 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/AudioFileAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/AudioFileAdapter.java
@@ -21,13 +21,13 @@
import cn.jpush.im.android.api.content.FileContent;
import jiguang.chat.R;
import jiguang.chat.activity.DownLoadActivity;
-import jiguang.chat.adapter.StickyListHeadersAdapter;
import jiguang.chat.entity.FileItem;
import jiguang.chat.entity.SelectedHistoryFileListener;
import jiguang.chat.utils.FileHelper;
import jiguang.chat.utils.SharePreferenceManager;
import jiguang.chat.utils.ViewHolder;
import jiguang.chat.view.MyImageView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
/**
* Created by ${chenyn} on 2017/8/29.
diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/DocumentFileAdapter.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/DocumentFileAdapter.java
index 3fd881c2..f0e33053 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/DocumentFileAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/DocumentFileAdapter.java
@@ -21,12 +21,12 @@
import cn.jpush.im.android.api.content.FileContent;
import jiguang.chat.R;
import jiguang.chat.activity.DownLoadActivity;
-import jiguang.chat.adapter.StickyListHeadersAdapter;
import jiguang.chat.entity.FileItem;
import jiguang.chat.entity.SelectedHistoryFileListener;
import jiguang.chat.utils.FileHelper;
import jiguang.chat.utils.SharePreferenceManager;
import jiguang.chat.utils.ViewHolder;
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
/**
* Created by ${chenyn} on 2017/8/29.
diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/OtherFileAdapter.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/OtherFileAdapter.java
index 73847c6d..341a714d 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/OtherFileAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/OtherFileAdapter.java
@@ -21,13 +21,13 @@
import cn.jpush.im.android.api.content.FileContent;
import jiguang.chat.R;
import jiguang.chat.activity.DownLoadActivity;
-import jiguang.chat.adapter.StickyListHeadersAdapter;
import jiguang.chat.entity.FileItem;
import jiguang.chat.entity.SelectedHistoryFileListener;
import jiguang.chat.utils.FileHelper;
import jiguang.chat.utils.SharePreferenceManager;
import jiguang.chat.utils.ViewHolder;
import jiguang.chat.view.MyImageView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
/**
* Created by ${chenyn} on 2017/8/29.
diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/VideoFileAdapter.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/VideoFileAdapter.java
index 5effb3ea..521deecf 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/VideoFileAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/adapter/VideoFileAdapter.java
@@ -21,13 +21,13 @@
import cn.jpush.im.android.api.content.FileContent;
import jiguang.chat.R;
import jiguang.chat.activity.DownLoadActivity;
-import jiguang.chat.adapter.StickyListHeadersAdapter;
import jiguang.chat.entity.FileItem;
import jiguang.chat.entity.SelectedHistoryFileListener;
import jiguang.chat.utils.FileHelper;
import jiguang.chat.utils.SharePreferenceManager;
import jiguang.chat.utils.ViewHolder;
import jiguang.chat.view.MyImageView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
/**
* Created by ${chenyn} on 2017/8/29.
diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/AudioFileFragment.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/AudioFileFragment.java
index 62934329..b74de258 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/AudioFileFragment.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/AudioFileFragment.java
@@ -26,7 +26,7 @@
import jiguang.chat.activity.historyfile.adapter.AudioFileAdapter;
import jiguang.chat.activity.historyfile.controller.HistoryFileController;
import jiguang.chat.entity.FileItem;
-import jiguang.chat.view.listview.StickyListHeadersListView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
/**
* Created by ${chenyn} on 2017/8/23.
diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/DocumentFileFragment.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/DocumentFileFragment.java
index 399c474a..c8ee6dc3 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/DocumentFileFragment.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/DocumentFileFragment.java
@@ -26,7 +26,7 @@
import jiguang.chat.activity.historyfile.adapter.DocumentFileAdapter;
import jiguang.chat.activity.historyfile.controller.HistoryFileController;
import jiguang.chat.entity.FileItem;
-import jiguang.chat.view.listview.StickyListHeadersListView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
/**
* Created by ${chenyn} on 2017/8/23.
diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/OtherFileFragment.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/OtherFileFragment.java
index db5308de..461d71ad 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/OtherFileFragment.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/OtherFileFragment.java
@@ -26,7 +26,7 @@
import jiguang.chat.activity.historyfile.adapter.OtherFileAdapter;
import jiguang.chat.activity.historyfile.controller.HistoryFileController;
import jiguang.chat.entity.FileItem;
-import jiguang.chat.view.listview.StickyListHeadersListView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
/**
* Created by ${chenyn} on 2017/8/23.
diff --git a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/VideoFileFragment.java b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/VideoFileFragment.java
index b76d91f9..55506b0d 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/VideoFileFragment.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/historyfile/fragment/VideoFileFragment.java
@@ -26,7 +26,7 @@
import jiguang.chat.activity.historyfile.adapter.VideoFileAdapter;
import jiguang.chat.activity.historyfile.controller.HistoryFileController;
import jiguang.chat.entity.FileItem;
-import jiguang.chat.view.listview.StickyListHeadersListView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
/**
* Created by ${chenyn} on 2017/8/23.
diff --git a/chatapp/src/main/java/jiguang/chat/activity/receiptmessage/MessageAlreadyReadFragment.java b/chatapp/src/main/java/jiguang/chat/activity/receiptmessage/MessageAlreadyReadFragment.java
index cf391130..1b4e48cc 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/receiptmessage/MessageAlreadyReadFragment.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/receiptmessage/MessageAlreadyReadFragment.java
@@ -30,6 +30,7 @@ public class MessageAlreadyReadFragment extends BaseFragment {
public MessageAlreadyReadFragment(long groupIdForReceipt) {
this.mGroupId = groupIdForReceipt;
}
+
public MessageAlreadyReadFragment() {
}
diff --git a/chatapp/src/main/java/jiguang/chat/activity/receiptmessage/MessageNotReadFragment.java b/chatapp/src/main/java/jiguang/chat/activity/receiptmessage/MessageNotReadFragment.java
index 2d840403..1d0e418a 100644
--- a/chatapp/src/main/java/jiguang/chat/activity/receiptmessage/MessageNotReadFragment.java
+++ b/chatapp/src/main/java/jiguang/chat/activity/receiptmessage/MessageNotReadFragment.java
@@ -19,7 +19,6 @@
/**
* Created by ${chenyn} on 2017/9/5.
*/
-
public class MessageNotReadFragment extends BaseFragment{
private Activity mContext;
private View mRootView;
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/AppsAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/AppsAdapter.java
index 60aae137..262f4a1d 100644
--- a/chatapp/src/main/java/jiguang/chat/adapter/AppsAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/adapter/AppsAdapter.java
@@ -8,9 +8,10 @@
import android.widget.ImageView;
import android.widget.TextView;
+import org.greenrobot.eventbus.EventBus;
+
import java.util.ArrayList;
-import cn.jpush.im.android.eventbus.EventBus;
import jiguang.chat.R;
import jiguang.chat.application.JGApplication;
import jiguang.chat.model.AppBean;
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/AtMemberAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/AtMemberAdapter.java
index 55c5180e..4a3b064c 100644
--- a/chatapp/src/main/java/jiguang/chat/adapter/AtMemberAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/adapter/AtMemberAdapter.java
@@ -19,6 +19,7 @@
import jiguang.chat.R;
import jiguang.chat.utils.ViewHolder;
import jiguang.chat.utils.pinyin.HanziToPinyin;
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
public class AtMemberAdapter extends BaseAdapter implements StickyListHeadersAdapter, SectionIndexer {
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomAdapter.java
new file mode 100644
index 00000000..79ce5a8a
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomAdapter.java
@@ -0,0 +1,76 @@
+package jiguang.chat.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.List;
+
+import cn.jpush.im.android.api.model.ChatRoomInfo;
+import jiguang.chat.R;
+import jiguang.chat.view.ChatRoomView;
+
+/**
+ * Created by ${chenyn} on 2017/10/31.
+ */
+
+public class ChatRoomAdapter extends BaseAdapter {
+ private Context mContext;
+ private List mChatRoomInfoList;
+ private ChatRoomView mChatRoomView;
+ private LayoutInflater mInflater;
+
+ public ChatRoomAdapter(Context context, List chatRoomData, ChatRoomView chatRoomView) {
+ this.mContext = context;
+ this.mChatRoomInfoList = chatRoomData;
+ this.mChatRoomView = chatRoomView;
+ this.mInflater = LayoutInflater.from(context);
+ }
+
+ @Override
+ public int getCount() {
+ return mChatRoomInfoList == null ? 0 : mChatRoomInfoList.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return mChatRoomInfoList.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup viewGroup) {
+ ViewHolder holder;
+ if (convertView == null) {
+ holder = new ViewHolder();
+ convertView = mInflater.inflate(R.layout.item_chat_room, null);
+ holder.iv_chatRoomAvatar = convertView.findViewById(R.id.iv_chatRoomAvatar);
+ holder.tv_chatRoomName = convertView.findViewById(R.id.tv_chatRoomName);
+ holder.tv_chatRoomContent = convertView.findViewById(R.id.tv_chatRoomContent);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ ChatRoomInfo chatRoomInfo = mChatRoomInfoList.get(position);
+ holder.tv_chatRoomName.setText(chatRoomInfo.getName());
+ holder.tv_chatRoomContent.setText(chatRoomInfo.getDescription());
+
+
+ return convertView;
+ }
+
+ class ViewHolder {
+ ImageView iv_chatRoomAvatar;
+ TextView tv_chatRoomName;
+ TextView tv_chatRoomContent;
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperGridAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperGridAdapter.java
new file mode 100644
index 00000000..59257cb6
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperGridAdapter.java
@@ -0,0 +1,60 @@
+package jiguang.chat.adapter;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+
+import java.util.List;
+
+import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback;
+import cn.jpush.im.android.api.model.UserInfo;
+import jiguang.chat.R;
+
+public class ChatRoomKeeperGridAdapter extends BaseAdapter {
+ private Context context;
+ private List keeperList;
+
+ public ChatRoomKeeperGridAdapter(Context context, List keeperList) {
+ this.context = context;
+ this.keeperList = keeperList;
+ }
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ImageView avatar;
+ if (convertView == null) {
+ convertView = LayoutInflater.from(context).inflate(R.layout.item_chatroom_avatar, null);
+ }
+ avatar = ((ImageView) convertView.findViewById(R.id.grid_avatar));
+ UserInfo userInfo = keeperList.get(position);
+ if (userInfo != null) {
+ userInfo.getAvatarBitmap(new GetAvatarBitmapCallback() {
+ @Override
+ public void gotResult(int i, String s, Bitmap bitmap) {
+ if (i == 0) {
+ avatar.setImageBitmap(bitmap);
+ }
+ }
+ });
+ }
+ return convertView;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return keeperList.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public int getCount() {
+ return keeperList != null ? keeperList.size() : 0;
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java
new file mode 100644
index 00000000..d8b0618f
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/adapter/ChatRoomKeeperListAdapter.java
@@ -0,0 +1,125 @@
+package jiguang.chat.adapter;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.Collections;
+import java.util.List;
+
+import cn.jpush.im.android.api.ChatRoomManager;
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback;
+import cn.jpush.im.android.api.model.UserInfo;
+import cn.jpush.im.api.BasicCallback;
+import jiguang.chat.R;
+import jiguang.chat.activity.ChatRoomKeeperActivity;
+import jiguang.chat.activity.GroupUserInfoActivity;
+import jiguang.chat.activity.PersonalActivity;
+import jiguang.chat.application.JGApplication;
+import jiguang.chat.utils.DialogCreator;
+
+public class ChatRoomKeeperListAdapter extends BaseAdapter implements AdapterView.OnItemClickListener {
+ private List keepers;
+ private Context context;
+ private LayoutInflater mInflater;
+ private long roomId;
+ private boolean isOwner;
+
+ public ChatRoomKeeperListAdapter(Context context, List keepers, long roomId, boolean isOwner) {
+ this.context = context;
+ this.keepers = keepers;
+ this.mInflater = LayoutInflater.from(context);
+ this.roomId = roomId;
+ this.isOwner = isOwner;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return keepers.get(position);
+ }
+
+ @Override
+ public int getCount() {
+ return keepers.size();
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+ if (convertView == null) {
+ holder = new ViewHolder();
+ convertView = mInflater.inflate(R.layout.item_chat_room_keeper, null);
+ holder.iv_keeperAvatar = convertView.findViewById(R.id.icon_iv);
+ holder.tv_keeperName = convertView.findViewById(R.id.name);
+ holder.bt_remove = convertView.findViewById(R.id.bt_removeKeeper);
+ if (!isOwner) {
+ holder.bt_remove.setVisibility(View.GONE);
+ } else {
+ holder.bt_remove.setOnClickListener((v)-> {
+ Dialog dialog = DialogCreator.createLoadingDialog(context, "移出中");
+ dialog.show();
+ ChatRoomManager.delChatRoomAdmin(roomId, Collections.singletonList(keepers.get(position).data), new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+ dialog.dismiss();
+ if (i == 0) {
+ keepers.remove(position);
+ notifyDataSetChanged();
+ }
+ }
+ });
+ });
+ }
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+ holder.iv_keeperAvatar.setImageResource(R.drawable.rc_default_portrait);
+ UserInfo userInfo = keepers.get(position).data;
+ userInfo.getAvatarBitmap(new GetAvatarBitmapCallback() {
+ @Override
+ public void gotResult(int i, String s, Bitmap bitmap) {
+ if (i == 0) {
+ holder.iv_keeperAvatar.setImageBitmap(bitmap);
+ }
+ }
+ });
+ holder.tv_keeperName.setText(keepers.get(position).highlight);
+ return convertView;
+ }
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ Intent intent = new Intent();
+ if (keepers.get(position).data.getUserID() == JMessageClient.getMyInfo().getUserID()) {
+ intent.setClass(context, PersonalActivity.class);
+ } else {
+ intent.setClass(context, GroupUserInfoActivity.class);
+ intent.putExtra(GroupUserInfoActivity.IS_FROM_GROUP, false);
+ intent.putExtra(JGApplication.NAME, keepers.get(position).data != null ? keepers.get(position).data.getUserName() : "");
+ intent.putExtra(JGApplication.TARGET_APP_KEY, keepers.get(position).data != null ? keepers.get(position).data.getAppKey() : "");
+ }
+ context.startActivity(intent);
+ }
+
+ class ViewHolder {
+ ImageView iv_keeperAvatar;
+ TextView tv_keeperName;
+ Button bt_remove;
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/ChattingListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/ChattingListAdapter.java
index c0ef6c34..719b1c05 100644
--- a/chatapp/src/main/java/jiguang/chat/adapter/ChattingListAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/adapter/ChattingListAdapter.java
@@ -96,6 +96,7 @@ public class ChattingListAdapter extends BaseAdapter {
private ChatItemController mController;
private Dialog mDialog;
private boolean mHasLastPage = false;
+ private boolean isChatRoom = false;
public ChattingListAdapter(Activity context, Conversation conv, ContentLongClickListener longClickListener) {
this.mContext = context;
@@ -123,10 +124,12 @@ public void gotResult(int status, String desc, Bitmap bitmap) {
}
});
}
- } else {
+ } else if (mConv.getType() == ConversationType.group) {
//群聊
GroupInfo groupInfo = (GroupInfo) mConv.getTargetInfo();
mGroupId = groupInfo.getGroupID();
+ } else {
+ isChatRoom = true;
}
checkSendingImgMsg();
}
@@ -169,6 +172,7 @@ public void dropDownToRefresh() {
List msgList = mConv.getMessagesFromNewest(mMsgList.size(), PAGE_MESSAGE_COUNT);
if (msgList != null) {
for (Message msg : msgList) {
+ // TODO:2019/04/23 这里是否效率低下,每次都需要移动整个list
mMsgList.add(0, msg);
}
if (msgList.size() > 0) {
@@ -224,8 +228,7 @@ private void checkSendingImgMsg() {
}
}
- public void setSendMsgs(int msgIds) {
- Message msg = mConv.getMessage(msgIds);
+ public void setSendMsgs(Message msg) {
if (msg != null) {
mMsgList.add(msg);
incrementStartPosition();
@@ -452,7 +455,7 @@ public void clearMsgList() {
public View getView(final int position, View convertView, ViewGroup parent) {
final Message msg = mMsgList.get(position);
//消息接收方发送已读回执
- if (msg.getDirect() == MessageDirect.receive && !msg.haveRead()) {
+ if (msg.getDirect() == MessageDirect.receive && !msg.haveRead() && !isChatRoom) {
msg.setHaveRead(new BasicCallback() {
@Override
public void gotResult(int i, String s) {
@@ -509,9 +512,7 @@ public void gotResult(int i, String s) {
holder.picture = (ImageView) convertView.findViewById(R.id.jmui_picture_iv);
holder.locationView = convertView.findViewById(R.id.location_view);
break;
- case custom:
- case prompt:
- case eventNotification:
+ default:
holder.groupChange = (TextView) convertView.findViewById(R.id.jmui_group_content);
break;
}
@@ -646,10 +647,18 @@ public void onClick(View arg0) {
case prompt:
mController.handlePromptMsg(msg, holder);
break;
- default:
+ case custom:
mController.handleCustomMsg(msg, holder);
+ break;
+ default:
+ mController.handleUnSupportMsg(msg, holder);
+ break;
+ }
+ if (isChatRoom && holder.text_receipt != null) {
+ holder.text_receipt.setVisibility(View.GONE);
}
- if (msg.getDirect() == MessageDirect.send && !msg.getContentType().equals(ContentType.prompt) && msg.getContentType() != ContentType.custom) {
+ if (msg.getDirect() == MessageDirect.send && !msg.getContentType().equals(ContentType.prompt)
+ && msg.getContentType() != ContentType.custom && !isChatRoom && msg.getContentType() != ContentType.video) {
if (msg.getUnreceiptCnt() == 0) {
if (msg.getTargetType() == ConversationType.group) {
holder.text_receipt.setText("全部已读");
@@ -880,4 +889,10 @@ public boolean onLongClick(View v) {
public abstract void onContentLongClick(int position, View view);
}
+ public void stopMediaPlayer() {
+ if (mController != null) {
+ mController.stopMediaPlayer();
+ }
+ }
+
}
\ No newline at end of file
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/ConversationListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/ConversationListAdapter.java
index 3961d0a3..3f363634 100644
--- a/chatapp/src/main/java/jiguang/chat/adapter/ConversationListAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/adapter/ConversationListAdapter.java
@@ -33,6 +33,7 @@
import cn.jpush.im.android.api.enums.ContentType;
import cn.jpush.im.android.api.enums.ConversationType;
import cn.jpush.im.android.api.enums.MessageDirect;
+import cn.jpush.im.android.api.enums.MessageStatus;
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.GroupInfo;
import cn.jpush.im.android.api.model.Message;
@@ -234,6 +235,7 @@ public View getView(final int position, View convertView, final ViewGroup parent
ImageView groupBlocked = ViewHolder.get(convertView, R.id.iv_groupBlocked);
ImageView newMsgDisturb = ViewHolder.get(convertView, R.id.new_group_msg_disturb);
ImageView newGroupMsgDisturb = ViewHolder.get(convertView, R.id.new_msg_disturb);
+ ImageView convListSendFail = ViewHolder.get(convertView, R.id.iv_convListSendFail);
final SwipeLayoutConv swipeLayout = ViewHolder.get(convertView, R.id.swp_layout);
final TextView delete = ViewHolder.get(convertView, R.id.tv_delete);
@@ -250,7 +252,7 @@ public View getView(final int position, View convertView, final ViewGroup parent
Message lastMsg = convItem.getLatestMessage();
if (lastMsg != null) {
TimeFormat timeFormat = new TimeFormat(mContext, lastMsg.getCreateTime());
-// //会话界面时间
+ //会话界面时间
datetime.setText(timeFormat.getTime());
String contentStr;
switch (lastMsg.getContentType()) {
@@ -294,6 +296,12 @@ public View getView(final int position, View convertView, final ViewGroup parent
break;
}
+ if (lastMsg.getStatus() == MessageStatus.send_fail) {
+ convListSendFail.setVisibility(View.VISIBLE);
+ }else {
+ convListSendFail.setVisibility(View.GONE);
+ }
+
MessageContent msgContent = lastMsg.getContent();
Boolean isRead = msgContent.getBooleanExtra("isRead");
Boolean isReadAtAll = msgContent.getBooleanExtra("isReadAtAll");
@@ -358,7 +366,11 @@ public View getView(final int position, View convertView, final ViewGroup parent
!lastMsg.getContentType().equals(ContentType.prompt) &&
//排除自己给自己发送消息
!((UserInfo) lastMsg.getTargetInfo()).getUserName().equals(JMessageClient.getMyInfo().getUserName())) {
- content.setText("[已读]" + contentStr);
+ if (lastMsg.getStatus() == MessageStatus.send_fail) {
+ content.setText(contentStr);
+ }else {
+ content.setText("[已读]" + contentStr);
+ }
} else {
content.setText(contentStr);
}
@@ -416,7 +428,7 @@ public void gotResult(int status, String desc, Bitmap bitmap) {
} else {
headIcon.setImageResource(R.drawable.jmui_head_icon);
}
- } else {
+ } else if (convItem.getType().equals(ConversationType.group)) {
mGroupInfo = (GroupInfo) convItem.getTargetInfo();
if (mGroupInfo != null) {
mGroupInfo.getAvatarBitmap(new GetAvatarBitmapCallback() {
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/FriendListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/FriendListAdapter.java
index 4c6a4b05..e90448f1 100644
--- a/chatapp/src/main/java/jiguang/chat/adapter/FriendListAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/adapter/FriendListAdapter.java
@@ -20,6 +20,7 @@
import cn.jpush.im.android.api.model.UserInfo;
import jiguang.chat.R;
import jiguang.chat.database.FriendEntry;
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
/**
* Created by ${chenyn} on 2017/9/21.
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/FriendRecommendAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/FriendRecommendAdapter.java
index 954e9624..d8ecd766 100644
--- a/chatapp/src/main/java/jiguang/chat/adapter/FriendRecommendAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/adapter/FriendRecommendAdapter.java
@@ -1,9 +1,10 @@
package jiguang.chat.adapter;
-import android.app.Activity;
import android.app.Dialog;
+import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -12,6 +13,8 @@
import android.widget.LinearLayout;
import android.widget.TextView;
+import org.greenrobot.eventbus.EventBus;
+
import java.util.ArrayList;
import java.util.List;
@@ -20,7 +23,6 @@
import cn.jpush.im.android.api.callback.GetUserInfoCallback;
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.UserInfo;
-import cn.jpush.im.android.eventbus.EventBus;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.activity.FriendInfoActivity;
@@ -46,19 +48,21 @@
public class FriendRecommendAdapter extends BaseAdapter {
- private Activity mContext;
+ private Fragment mFragment;
+ private Context mContext;
private List mList = new ArrayList<>();
private LayoutInflater mInflater;
private float mDensity;
private int mWidth;
- public FriendRecommendAdapter(Activity context, List list, float density,
+ public FriendRecommendAdapter(Fragment fragment, List list, float density,
int width) {
- this.mContext = context;
- this.mList = list;
- this.mInflater = LayoutInflater.from(mContext);
- this.mDensity = density;
- this.mWidth = width;
+ mFragment = fragment;
+ mContext = mFragment.getActivity();
+ mList = list;
+ mInflater = LayoutInflater.from(mContext);
+ mDensity = density;
+ mWidth = width;
}
@Override
@@ -201,7 +205,7 @@ public void onClick(View view) {
intent.putExtra("position", position);
intent.putExtra(JGApplication.TARGET_ID, entry.username);
intent.putExtra(JGApplication.TARGET_APP_KEY, entry.appKey);
- mContext.startActivityForResult(intent, 0);
+ mFragment.startActivityForResult(intent, 0);
//2.已经添加的 --> 好友详情
} else if (entry.state.equals(FriendInvitation.ACCEPTED.getValue())) {
JMessageClient.getUserInfo(item.username, new GetUserInfoCallback() {
@@ -217,7 +221,7 @@ public void gotResult(int i, String s, UserInfo userInfo) {
}
intent1.putExtra(JGApplication.TARGET_ID, entry.username);
intent1.putExtra(JGApplication.TARGET_APP_KEY, entry.appKey);
- mContext.startActivityForResult(intent1, 0);
+ mFragment.startActivityForResult(intent1, 0);
}
}
});
@@ -228,7 +232,7 @@ public void gotResult(int i, String s, UserInfo userInfo) {
intent.putExtra("reason", item.reason);
intent.putExtra(JGApplication.TARGET_ID, entry.username);
intent.putExtra(JGApplication.TARGET_APP_KEY, entry.appKey);
- mContext.startActivityForResult(intent, 0);
+ mFragment.startActivityForResult(intent, 0);
}
}
@@ -297,7 +301,7 @@ public void onClick(View view) {
}
intent.putExtra(JGApplication.TARGET_ID, entry.username);
intent.putExtra(JGApplication.TARGET_APP_KEY, entry.appKey);
- mContext.startActivityForResult(intent, 0);
+ mFragment.startActivityForResult(intent, 0);
}
});
}
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/GroupListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/GroupListAdapter.java
index 7e77b040..900ee4b7 100644
--- a/chatapp/src/main/java/jiguang/chat/adapter/GroupListAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/adapter/GroupListAdapter.java
@@ -15,6 +15,8 @@
import android.widget.TextView;
import android.widget.Toast;
+import org.greenrobot.eventbus.EventBus;
+
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -27,7 +29,6 @@
import cn.jpush.im.android.api.model.Message;
import cn.jpush.im.android.api.model.UserInfo;
import cn.jpush.im.android.api.options.MessageSendingOptions;
-import cn.jpush.im.android.eventbus.EventBus;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.activity.ChatActivity;
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/GroupMemberGridAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/GroupMemberGridAdapter.java
index 0cfbd010..9d10cc54 100644
--- a/chatapp/src/main/java/jiguang/chat/adapter/GroupMemberGridAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/adapter/GroupMemberGridAdapter.java
@@ -34,7 +34,7 @@ public class GroupMemberGridAdapter extends BaseAdapter {
private int mCurrentNum;
//用群成员项数余4得到,作为下标查找mRestArray,得到空白项
private int mRestNum;
- private static final int MAX_GRID_ITEM = 40;
+ private int maxGridItem;
private boolean mIsGroup;
private String mTargetId;
private Context mContext;
@@ -53,6 +53,7 @@ public GroupMemberGridAdapter(Context context, List memberList, boolea
this.mMemberList = memberList;
mCurrentNum = mMemberList.size();
this.mIsCreator = isCreator;
+ maxGridItem = isCreator ? 13 : 14;
this.mAvatarSize = size;
initBlankItem(mCurrentNum);
}
@@ -66,8 +67,8 @@ public GroupMemberGridAdapter(Context context, String targetId, String appKey) {
}
public void initBlankItem(int size) {
- if (mMemberList.size() > MAX_GRID_ITEM) {
- mCurrentNum = MAX_GRID_ITEM - 1;
+ if (mMemberList.size() > maxGridItem) {
+ mCurrentNum = maxGridItem;
} else {
mCurrentNum = mMemberList.size();
}
@@ -75,8 +76,8 @@ public void initBlankItem(int size) {
}
public void refreshMemberList() {
- if (mMemberList.size() > MAX_GRID_ITEM) {
- mCurrentNum = MAX_GRID_ITEM - 1;
+ if (mMemberList.size() > maxGridItem) {
+ mCurrentNum = maxGridItem;
} else {
mCurrentNum = mMemberList.size();
}
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/GroupMemberListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/GroupMemberListAdapter.java
new file mode 100644
index 00000000..faeeba13
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/adapter/GroupMemberListAdapter.java
@@ -0,0 +1,238 @@
+package jiguang.chat.adapter;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.SectionIndexer;
+import android.widget.TextView;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback;
+import cn.jpush.im.android.api.callback.GetGroupInfoCallback;
+import cn.jpush.im.android.api.model.GroupInfo;
+import cn.jpush.im.android.api.model.UserInfo;
+import jiguang.chat.R;
+import jiguang.chat.activity.GroupMemberListActivity;
+import jiguang.chat.utils.pinyin.HanziToPinyin;
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
+
+/**
+ * Created by ${chenyn} on 2017/11/3.
+ */
+
+public class GroupMemberListAdapter extends BaseAdapter implements StickyListHeadersAdapter, SectionIndexer {
+
+ private List mMemberList;
+ private final LayoutInflater mInflater;
+
+ private int[] mSectionIndices;
+ private String[] mSectionLetters;
+ private long mGroupID;
+
+ public GroupMemberListAdapter(GroupMemberListActivity context, List memberInfoList, long groupId) {
+ mInflater = LayoutInflater.from(context);
+ this.mMemberList = memberInfoList;
+ this.mGroupID = groupId;
+
+ //想要给listView增加分组,数据源要排序才行
+ mSectionIndices = getSectionIndices();
+ mSectionLetters = getSectionLetters();
+ }
+
+ @Override
+ public int getCount() {
+ return mMemberList == null ? 0 : mMemberList.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mMemberList.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder viewholder;
+ if (convertView == null) {
+ viewholder = new ViewHolder();
+ convertView = mInflater.inflate(R.layout.item_group_member_list, parent, false);
+ viewholder.iv_memberAvatar = convertView.findViewById(R.id.iv_memberAvatar);
+ viewholder.tv_memberName = convertView.findViewById(R.id.tv_memberName);
+ viewholder.iv_gag = convertView.findViewById(R.id.iv_silence);
+ convertView.setTag(viewholder);
+ } else {
+ viewholder = (ViewHolder) convertView.getTag();
+ }
+
+ UserInfo userInfo = mMemberList.get(position);
+ File file = userInfo.getAvatarFile();
+ if (file != null) {
+ if (file.exists()) {
+ viewholder.iv_memberAvatar.setImageBitmap(BitmapFactory.decodeFile(userInfo.getAvatarFile().getPath()));
+ } else {
+ userInfo.getBigAvatarBitmap(new GetAvatarBitmapCallback() {
+ @Override
+ public void gotResult(int i, String s, Bitmap bitmap) {
+ if (i == 0) {
+ viewholder.iv_memberAvatar.setImageBitmap(bitmap);
+ }
+ }
+ });
+ }
+ } else {
+ viewholder.iv_memberAvatar.setImageResource(R.drawable.jmui_head_icon);
+ }
+
+ viewholder.tv_memberName.setText(userInfo.getDisplayName());
+
+ JMessageClient.getGroupInfo(mGroupID, new GetGroupInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, GroupInfo groupInfo) {
+ if (i == 0) {
+ boolean keepSilence = groupInfo.isKeepSilence(userInfo.getUserName(), userInfo.getAppKey());
+ if (keepSilence) {
+ viewholder.iv_gag.setVisibility(View.VISIBLE);
+ }else {
+ viewholder.iv_gag.setVisibility(View.GONE);
+ }
+ }
+ }
+ });
+
+ return convertView;
+ }
+
+ @Override
+ public View getHeaderView(int position, View convertView, ViewGroup parent) {
+ convertView = mInflater.inflate(R.layout.header, parent, false);
+ TextView headView = convertView.findViewById(R.id.section_tv);
+ UserInfo userInfo = mMemberList.get(position);
+
+ int forPosition = getSectionForPosition(position);
+ headView.setText(getLetter(userInfo.getDisplayName()));
+ if (position == getPositionForSection(forPosition)) {
+ headView.setText(getLetter(userInfo.getDisplayName()));
+ }
+ return convertView;
+ }
+
+ @Override
+ public long getHeaderId(int position) {
+ String letter = getLetter(mMemberList.get(position).getDisplayName());
+ return letter.charAt(0);
+ }
+
+ class ViewHolder {
+ ImageView iv_memberAvatar;
+ TextView tv_memberName;
+ ImageView iv_gag;
+ }
+
+ private int[] getSectionIndices() {
+ ArrayList sectionIndices = new ArrayList();
+ if (mMemberList.size() > 0) {
+ char lastFirstChar = getLetter(mMemberList.get(0).getDisplayName()).charAt(0);
+ sectionIndices.add(0);
+ for (int i = 1; i < mMemberList.size(); i++) {
+ if (getLetter(mMemberList.get(i).getDisplayName()).charAt(0) != lastFirstChar) {
+ lastFirstChar = getLetter(mMemberList.get(i).getDisplayName()).charAt(0);
+ sectionIndices.add(i);
+ }
+ }
+ int[] sections = new int[sectionIndices.size()];
+ for (int i = 0; i < sectionIndices.size(); i++) {
+ sections[i] = sectionIndices.get(i);
+ }
+ return sections;
+ }
+ return null;
+ }
+
+ private String[] getSectionLetters() {
+ if (null != mSectionIndices) {
+ String[] letters = new String[mSectionIndices.length];
+ for (int i = 0; i < mSectionIndices.length; i++) {
+ letters[i] = getLetter(mMemberList.get(mSectionIndices[i]).getDisplayName());
+ }
+ return letters;
+ }
+ return null;
+ }
+
+ @Override
+ public Object[] getSections() {
+ return mSectionLetters;
+ }
+
+ @Override
+ public int getPositionForSection(int sectionIndex) {
+ if (mSectionIndices == null || mSectionIndices.length == 0) {
+ return 0;
+ }
+ if (sectionIndex >= mSectionIndices.length) {
+ sectionIndex = mSectionIndices.length - 1;
+ } else if (sectionIndex < 0) {
+ sectionIndex = 0;
+ }
+ return mSectionIndices[sectionIndex];
+ }
+
+ @Override
+ public int getSectionForPosition(int position) {
+ if (null != mSectionIndices) {
+ for (int i = 0; i < mSectionIndices.length; i++) {
+ if (position < mSectionIndices[i]) {
+ return i - 1;
+ }
+ }
+ return mSectionIndices.length - 1;
+ }
+ return -1;
+ }
+
+ public int getSectionForLetter(String letter) {
+ if (null != mSectionIndices) {
+ for (int i = 0; i < mSectionIndices.length; i++) {
+ if (mSectionLetters[i].equals(letter)) {
+ return mSectionIndices[i] + 1;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public String getLetter(String name) {
+ String letter;
+ ArrayList tokens = HanziToPinyin.getInstance()
+ .get(name);
+ StringBuilder sb = new StringBuilder();
+ if (tokens != null && tokens.size() > 0) {
+ for (HanziToPinyin.Token token : tokens) {
+ if (token.type == HanziToPinyin.Token.PINYIN) {
+ sb.append(token.target);
+ } else {
+ sb.append(token.source);
+ }
+ }
+ }
+ String sortString = sb.toString().substring(0, 1).toUpperCase();
+ if (sortString.matches("[A-Z]")) {
+ letter = sortString.toUpperCase();
+ } else {
+ letter = "#";
+ }
+ return letter;
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/GroupVerificationAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/GroupVerificationAdapter.java
new file mode 100644
index 00000000..c5c8af08
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/adapter/GroupVerificationAdapter.java
@@ -0,0 +1,222 @@
+package jiguang.chat.adapter;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.google.gson.Gson;
+
+import java.io.File;
+import java.util.List;
+
+import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.callback.GetAvatarBitmapCallback;
+import cn.jpush.im.android.api.callback.GetGroupInfoCallback;
+import cn.jpush.im.android.api.callback.GetUserInfoCallback;
+import cn.jpush.im.android.api.event.GroupApprovalEvent;
+import cn.jpush.im.android.api.model.GroupInfo;
+import cn.jpush.im.android.api.model.UserInfo;
+import cn.jpush.im.api.BasicCallback;
+import jiguang.chat.R;
+import jiguang.chat.database.GroupApplyEntry;
+
+/**
+ * Created by ${chenyn} on 2017/11/7.
+ */
+
+public class GroupVerificationAdapter extends BaseAdapter {
+ private Activity mContext;
+ private final LayoutInflater mInflater;
+ private List recommends;
+ private File mFile;
+
+ public GroupVerificationAdapter(Activity context, List recommends) {
+ this.mContext = context;
+ this.recommends = recommends;
+ mInflater = LayoutInflater.from(mContext);
+ }
+
+ @Override
+ public int getCount() {
+ return recommends.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return recommends.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ GroupApplyEntry entry = recommends.get(position);
+
+ ViewHolder holder;
+ if (convertView == null) {
+ holder = new ViewHolder();
+ convertView = mInflater.inflate(R.layout.item_group_owner_recomend, null);
+ holder.iv_groupAvatar = convertView.findViewById(R.id.item_head_icon);
+ holder.item_name = convertView.findViewById(R.id.item_name);
+ holder.item_reason = convertView.findViewById(R.id.item_reason);
+ holder.tv_groupInvite = convertView.findViewById(R.id.tv_groupInvite);
+ holder.item_add_btn = convertView.findViewById(R.id.item_add_btn);
+ holder.item_state = convertView.findViewById(R.id.item_state);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ if (entry.Avatar != null) {
+ mFile = new File(entry.Avatar);
+ if (mFile.exists()) {
+ holder.iv_groupAvatar.setImageBitmap(BitmapFactory.decodeFile(entry.Avatar));
+ } else {
+ JMessageClient.getUserInfo(entry.toUsername, new GetUserInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, UserInfo userInfo) {
+ if (i == 0) {
+ userInfo.getAvatarBitmap(new GetAvatarBitmapCallback() {
+ @Override
+ public void gotResult(int i, String s, Bitmap bitmap) {
+ if (i == 0) {
+ holder.iv_groupAvatar.setImageBitmap(bitmap);
+ } else {
+ holder.iv_groupAvatar.setImageResource(R.drawable.jmui_head_icon);
+ }
+ }
+ });
+ }
+ }
+ });
+ }
+ } else {
+ holder.iv_groupAvatar.setImageResource(R.drawable.jmui_head_icon);
+
+ }
+
+
+ JMessageClient.getGroupInfo(Long.parseLong(entry.groupName), new GetGroupInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, GroupInfo groupInfo) {
+ holder.item_reason.setText("申请加入群 " + groupInfo.getGroupName());
+ //邀请
+ if (entry.groupType == 0) {
+ holder.item_name.setText(entry.toDisplayName);
+ holder.tv_groupInvite.setText("邀请人:" + entry.fromDisplayName);//事件发起人
+ } else {
+ holder.item_name.setText(entry.toDisplayName);
+ holder.tv_groupInvite.setText(entry.reason);
+ }
+ }
+ });
+
+ //申请
+ //0为初始状态
+ Gson gson = new Gson();
+ GroupApprovalEvent event = gson.fromJson(entry.eventJson, GroupApprovalEvent.class);
+ if (entry.btnState == 0) {
+ holder.item_add_btn.setBackgroundColor(Color.parseColor("#2DD0CF"));
+ holder.item_add_btn.setTextColor(Color.parseColor("#FFFFFF"));
+ holder.item_add_btn.setText("同意");
+ holder.item_add_btn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ //邀请
+ event.acceptGroupApproval(entry.toUsername, entry.appKey, new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+ if (i == 0) {
+ //同意加入群组
+ Toast.makeText(mContext, "添加成功", Toast.LENGTH_SHORT).show();
+ holder.item_add_btn.setBackgroundColor(Color.parseColor("#FFFFFF"));
+ holder.item_add_btn.setTextColor(Color.parseColor("#B5B5B6"));
+ holder.item_add_btn.setText("已同意");
+ entry.btnState = 1;
+ entry.save();
+ notifyDataSetChanged();
+ } else {
+ Toast.makeText(mContext, "添加失败1" + s + i, Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+
+ }
+ });
+ //同意
+ } else if (entry.btnState == 1) {
+ holder.item_add_btn.setBackgroundColor(Color.parseColor("#FFFFFF"));
+ holder.item_add_btn.setTextColor(Color.parseColor("#B5B5B6"));
+ holder.item_add_btn.setText("已同意");
+ event.acceptGroupApproval(entry.toUsername, entry.appKey, new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+ if (i == 0) {
+ //同意加入群组
+ Toast.makeText(mContext, "添加成功", Toast.LENGTH_SHORT).show();
+ holder.item_add_btn.setBackgroundColor(Color.parseColor("#FFFFFF"));
+ holder.item_add_btn.setTextColor(Color.parseColor("#B5B5B6"));
+ holder.item_add_btn.setText("已同意");
+ entry.btnState = 1;
+ entry.save();
+ notifyDataSetChanged();
+ } else if (i == 856001) {
+ holder.item_add_btn.setBackgroundColor(Color.parseColor("#FFFFFF"));
+ holder.item_add_btn.setTextColor(Color.parseColor("#B5B5B6"));
+ holder.item_add_btn.setText("已同意");
+ } else {
+ Toast.makeText(mContext, "添加失败..." + s + i, Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+
+ //拒绝
+ } else if (entry.btnState == 2) {
+ event.refuseGroupApproval(entry.toUsername, entry.appKey, "拒绝加入", new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+ if (i == 0) {
+ Toast.makeText(mContext, "拒绝成功", Toast.LENGTH_SHORT).show();
+ holder.item_add_btn.setBackgroundColor(Color.parseColor("#FFFFFF"));
+ holder.item_add_btn.setTextColor(Color.parseColor("#B5B5B6"));
+ holder.item_add_btn.setText("已拒绝");
+ entry.btnState = 2;
+ entry.save();
+ } else if (i == 856002) {
+ holder.item_add_btn.setBackgroundColor(Color.parseColor("#FFFFFF"));
+ holder.item_add_btn.setTextColor(Color.parseColor("#B5B5B6"));
+ holder.item_add_btn.setText("已拒绝");
+ } else {
+ Toast.makeText(mContext, "拒绝失败" + s + i, Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+
+ }
+
+
+ return convertView;
+ }
+
+ class ViewHolder {
+ ImageView iv_groupAvatar;
+ TextView item_name;
+ TextView item_reason;
+ TextView tv_groupInvite;
+ TextView item_add_btn;
+ TextView item_state;
+ }
+
+
+}
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/StickyListAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/StickyListAdapter.java
index 16b8f3ea..4c440cef 100644
--- a/chatapp/src/main/java/jiguang/chat/adapter/StickyListAdapter.java
+++ b/chatapp/src/main/java/jiguang/chat/adapter/StickyListAdapter.java
@@ -43,6 +43,7 @@
import jiguang.chat.application.JGApplication;
import jiguang.chat.database.FriendEntry;
import jiguang.chat.utils.photochoose.SelectableRoundedImageView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
/**
* Created by ${chenyn} on 2017/3/16.
@@ -231,7 +232,18 @@ public void gotResult(int i, String s, Bitmap bitmap) {
}
final long[] uid = new long[1];
- uid[0] = friend.uid;
+ if (friend.uid == null) {
+ JMessageClient.getUserInfo(friend.username, new GetUserInfoCallback() {
+ @Override
+ public void gotResult(int i, String s, UserInfo userInfo) {
+ if (i == 0) {
+ uid[0] = userInfo.getUserID();
+ }
+ }
+ });
+ } else {
+ uid[0] = friend.uid;
+ }
if (!mIsSearch) {
holder.displayName.setText(friend.displayName);
} else {
diff --git a/chatapp/src/main/java/jiguang/chat/adapter/StickyListHeadersAdapter.java b/chatapp/src/main/java/jiguang/chat/adapter/StickyListHeadersAdapter.java
deleted file mode 100644
index d818daee..00000000
--- a/chatapp/src/main/java/jiguang/chat/adapter/StickyListHeadersAdapter.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package jiguang.chat.adapter;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListAdapter;
-
-public interface StickyListHeadersAdapter extends ListAdapter {
- /**
- * Get a View that displays the header data at the specified position in the
- * set. You can either create a View manually or inflate it from an XML layout
- * file.
- *
- * @param position
- * The position of the item within the adapter's data set of the item whose
- * header view we want.
- * @param convertView
- * The old view to reuse, if possible. Note: You should check that this view is
- * non-null and of an appropriate type before using. If it is not possible to
- * convert this view to display the correct data, this method can create a new
- * view.
- * @param parent
- * The parent that this view will eventually be attached to.
- * @return
- * A View corresponding to the data at the specified position.
- */
- View getHeaderView(int position, View convertView, ViewGroup parent);
-
- /**
- * Get the header id associated with the specified position in the list.
- *
- * @param position
- * The position of the item within the adapter's data set whose header id we
- * want.
- * @return
- * The id of the header at the specified position.
- */
- long getHeaderId(int position);
-}
diff --git a/chatapp/src/main/java/jiguang/chat/application/JGApplication.java b/chatapp/src/main/java/jiguang/chat/application/JGApplication.java
index e603d071..ceb39158 100644
--- a/chatapp/src/main/java/jiguang/chat/application/JGApplication.java
+++ b/chatapp/src/main/java/jiguang/chat/application/JGApplication.java
@@ -13,6 +13,7 @@
import java.util.Map;
import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.GroupInfo;
import cn.jpush.im.android.api.model.Message;
import cn.jpush.im.android.api.model.UserInfo;
@@ -76,14 +77,19 @@ public class JGApplication extends com.activeandroid.app.Application {
public static final int REQUEST_CODE_SEND_LOCATION = 24;
public static final int REQUEST_CODE_FRIEND_INFO = 16;
public static final int RESULT_CODE_CHAT_DETAIL = 15;
+ public static final int REQUEST_CODE_FRIEND_LIST = 17;
public static final int ON_GROUP_EVENT = 3004;
public static final String DELETE_MODE = "deleteMode";
public static final int RESULT_CODE_ME_INFO = 20;
public static final String DRAFT = "draft";
+ public static final String CONV_TYPE = "conversationType"; //value使用 ConversationType
+ public static final String ROOM_ID = "roomId";
public static final String GROUP_ID = "groupId";
public static final String POSITION = "position";
public static final String MsgIDs = "msgIDs";
+ public static final String MSG_JSON = "msg_json";
+ public static final String MSG_LIST_JSON = "msg_list_json";
public static final String NAME = "name";
public static final String ATALL = "atall";
public static final String SEARCH_AT_MEMBER_NAME = "search_at_member_name";
@@ -96,11 +102,13 @@ public class JGApplication extends com.activeandroid.app.Application {
private static final String JCHAT_CONFIGS = "JChat_configs";
public static String FILE_DIR = "sdcard/JChatDemo/recvFiles/";
public static String VIDEO_DIR = "sdcarVIDEOd/JChatDemo/sendFiles/";
+ public static String THUMP_PICTURE_DIR;
public static final String TARGET_ID = "targetId";
public static final String ATUSER = "atuser";
public static final String TARGET_APP_KEY = "targetAppKey";
public static int maxImgCount; //允许选择图片最大数
public static final String GROUP_NAME = "groupName";
+ public static String groupAvatarPath;
public static Context context;
public static LocationService locationService;
@@ -113,13 +121,16 @@ public class JGApplication extends com.activeandroid.app.Application {
public static List alreadyRead = new ArrayList<>();
public static List unRead = new ArrayList<>();
public static List forAddFriend = new ArrayList<>();
+ public static List forAddIntoGroup = new ArrayList<>();
+ public static Conversation delConversation;
+ public static ArrayList selectedUser;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
+ THUMP_PICTURE_DIR = context.getFilesDir().getAbsolutePath() + "/JChatDemo";
StorageUtil.init(context, null);
-
Fresco.initialize(getApplicationContext());
SDKInitializer.initialize(getApplicationContext());
locationService = new LocationService(getApplicationContext());
diff --git a/chatapp/src/main/java/jiguang/chat/controller/ChatDetailController.java b/chatapp/src/main/java/jiguang/chat/controller/ChatDetailController.java
index 4fe14a7e..3bc58f5c 100644
--- a/chatapp/src/main/java/jiguang/chat/controller/ChatDetailController.java
+++ b/chatapp/src/main/java/jiguang/chat/controller/ChatDetailController.java
@@ -1,5 +1,6 @@
package jiguang.chat.controller;
+import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Intent;
import android.os.Handler;
@@ -17,6 +18,8 @@
import android.widget.LinearLayout;
import android.widget.Toast;
+import org.greenrobot.eventbus.EventBus;
+
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -33,17 +36,18 @@
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.GroupInfo;
import cn.jpush.im.android.api.model.UserInfo;
-import cn.jpush.im.android.eventbus.EventBus;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.activity.ChatDetailActivity;
import jiguang.chat.activity.FriendInfoActivity;
import jiguang.chat.activity.GroupAvatarActivity;
-import jiguang.chat.activity.GroupGridViewActivity;
+import jiguang.chat.activity.GroupMemberListActivity;
import jiguang.chat.activity.GroupNotFriendActivity;
+import jiguang.chat.activity.GroupUserInfoActivity;
import jiguang.chat.activity.MainActivity;
import jiguang.chat.activity.MembersInChatActivity;
import jiguang.chat.activity.PersonalActivity;
+import jiguang.chat.activity.SilenceUsersActivity;
import jiguang.chat.activity.VerificationActivity;
import jiguang.chat.activity.historyfile.activity.HistoryFileActivity;
import jiguang.chat.adapter.GroupMemberGridAdapter;
@@ -80,7 +84,7 @@ public class ChatDetailController implements OnClickListener, OnItemClickListene
private Dialog mLoadingDialog = null;
private static final int ADD_MEMBERS_TO_GRIDVIEW = 2048;
private static final int ADD_A_MEMBER_TO_GRIDVIEW = 2049;
- private static final int MAX_GRID_ITEM = 40;
+ private int maxGridItem = 40;
private String mGroupName;
private String mGroupDesc;
private final MyHandler myHandler = new MyHandler(this);
@@ -98,6 +102,7 @@ public class ChatDetailController implements OnClickListener, OnItemClickListene
private String mAvatarPath;
private boolean mFriend;
private Long mUid;
+ private String mGroupOwnerId;
public ChatDetailController(ChatDetailView chatDetailView, ChatDetailActivity context, int size,
int width) {
@@ -129,7 +134,10 @@ public void initData() {
mGroupInfo = (GroupInfo) conv.getTargetInfo();
mChatDetailView.initNoDisturb(mGroupInfo.getNoDisturb());
mMemberInfoList = mGroupInfo.getGroupMembers();
- String groupOwnerId = mGroupInfo.getGroupOwner();
+ mChatDetailView.setMemberCount(" " + mMemberInfoList.size() + " 人");
+ mChatDetailView.setGroupId(mGroupId + "");
+ mChatDetailView.setGroupType(mGroupInfo.getGroupFlag() == 2 ? "普通群" : "私有群");
+ mGroupOwnerId = mGroupInfo.getGroupOwner();
mGroupName = mGroupInfo.getGroupName();
mGroupDesc = mGroupInfo.getGroupDescription();
if (mGroupInfo.getAvatarFile() != null && mGroupInfo.getAvatarFile().exists()) {
@@ -150,9 +158,10 @@ public void initData() {
}
// 判断是否为群主
- if (groupOwnerId != null && groupOwnerId.equals(mMyUsername)) {
+ if (mGroupOwnerId != null && mGroupOwnerId.equals(mMyUsername)) {
mIsCreator = true;
}
+ maxGridItem = mIsCreator ? 13 : 14;
mChatDetailView.setMyName(mMyUsername);
mChatDetailView.showBlockView(mGroupInfo.isGroupBlocked());
initAdapter();
@@ -178,7 +187,6 @@ public void initData() {
mChatDetailView.setAdapter(mGridAdapter);
// 设置单聊界面
mChatDetailView.setSingleView(mUserInfo.isFriend());
- mChatDetailView.dismissAllMembersBtn();
mChatDetailView.isLoadMoreShow(false);
JMessageClient.getUserInfo(mTargetId, new GetUserInfoCallback() {
@@ -206,8 +214,8 @@ public void gotResult(int i, String s, UserInfo userInfo) {
private void initAdapter() {
// 初始化头像
mGridAdapter = new GroupMemberGridAdapter(mContext, mMemberInfoList, mIsCreator, mAvatarSize);
- if (mMemberInfoList.size() > MAX_GRID_ITEM) {
- mCurrentNum = MAX_GRID_ITEM - 1;
+ if (mMemberInfoList.size() > maxGridItem) {
+ mCurrentNum = maxGridItem;
} else {
mCurrentNum = mMemberInfoList.size();
}
@@ -215,6 +223,7 @@ private void initAdapter() {
mChatDetailView.getGridView().setFocusable(false);
}
+ @SuppressLint("WrongConstant")
@Override
public void onClick(View v) {
Intent intent = new Intent();
@@ -236,11 +245,11 @@ public void onClick(View v) {
break;
case R.id.rl_groupAvatar:
intent.setClass(mContext, GroupAvatarActivity.class);
- intent.putExtra("groupID",mGroupId);
- if(mGroupInfo.getBigAvatarFile() != null && mGroupInfo.getBigAvatarFile().exists()) {
+ intent.putExtra("groupID", mGroupId);
+ if (mGroupInfo.getBigAvatarFile() != null && mGroupInfo.getBigAvatarFile().exists()) {
intent.putExtra("groupAvatar", mGroupInfo.getBigAvatarFile().getAbsolutePath());
}
- mContext.startActivityForResult(intent,4);
+ mContext.startActivityForResult(intent, 4);
break;
// 删除聊天记录
case R.id.group_chat_del_ll:
@@ -298,7 +307,11 @@ public void onClick(View view) {
mDialog.show();
break;
case R.id.tv_moreGroup:
- intent.setClass(mContext, GroupGridViewActivity.class);
+ case R.id.moreGroupMember:
+ //群成员列表,gridView
+ //intent.setClass(mContext, GroupGridViewActivity.class);
+ //群成员list列表
+ intent.setClass(mContext, GroupMemberListActivity.class);
intent.putExtra(JGApplication.GROUP_ID, mGroupId);
intent.putExtra(JGApplication.DELETE_MODE, false);
mContext.startActivityForResult(intent, JGApplication.REQUEST_CODE_ALL_MEMBER);
@@ -413,6 +426,12 @@ public void onClick(View v) {
mContext.startActivity(intent);
mContext.overridePendingTransition(R.anim.trans_in, R.anim.trans_out);
break;
+ //跳转群禁言列表
+ case R.id.chat_silence:
+ intent = new Intent(mContext, SilenceUsersActivity.class);
+ intent.putExtra("groupID", mGroupId);
+ mContext.startActivity(intent);
+ break;
}
}
@@ -497,16 +516,20 @@ public void onItemClick(AdapterView> viewAdapter, View view, final int positio
intent.setClass(mContext, PersonalActivity.class);
} else {
UserInfo userInfo = mMemberInfoList.get(position);
+ intent.setClass(mContext, GroupUserInfoActivity.class);
+ intent.putExtra("groupID",mGroupId);
+ intent.putExtra("groupUserName",userInfo.getUserName());
+ intent.putExtra("groupOwner",mGroupOwnerId);
//是否是好友
- if (userInfo.isFriend()) {
- intent.setClass(mContext, FriendInfoActivity.class);
- intent.putExtra("group_grid", true);
- } else {
- intent.setClass(mContext, GroupNotFriendActivity.class);
- }
- intent.putExtra(JGApplication.TARGET_ID, userInfo.getUserName());
- intent.putExtra(JGApplication.TARGET_APP_KEY, userInfo.getAppKey());
- intent.putExtra(JGApplication.GROUP_ID, mGroupId);
+// if (userInfo.isFriend()) {
+// intent.setClass(mContext, FriendInfoActivity.class);
+// intent.putExtra("group_grid", true);
+// } else {
+// intent.setClass(mContext, GroupNotFriendActivity.class);
+// }
+// intent.putExtra(JGApplication.TARGET_ID, userInfo.getUserName());
+// intent.putExtra(JGApplication.TARGET_APP_KEY, userInfo.getAppKey());
+// intent.putExtra(JGApplication.GROUP_ID, mGroupId);
}
mContext.startActivity(intent);
// 点击添加成员按钮
@@ -603,6 +626,8 @@ private void addMembers(ArrayList users) {
public void gotResult(final int status, final String desc) {
mLoadingDialog.dismiss();
if (status == 0) {
+ mMemberInfoList.clear();
+ mMemberInfoList.addAll(mGroupInfo.getGroupMembers());
refreshMemberList();
} else {
ToastUtil.shortToast(mContext, "添加失败");
@@ -613,7 +638,7 @@ public void gotResult(final int status, final String desc) {
//添加或者删除成员后重新获得MemberInfoList
public void refreshMemberList() {
- mCurrentNum = mMemberInfoList.size() > MAX_GRID_ITEM ? MAX_GRID_ITEM - 1 : mMemberInfoList.size();
+ mCurrentNum = mMemberInfoList.size() > maxGridItem ? maxGridItem : mMemberInfoList.size();
mGridAdapter.refreshMemberList();
}
@@ -888,7 +913,10 @@ public GroupMemberGridAdapter getAdapter() {
*/
public void refresh(long groupId) {
//当前群聊
- if (mGroupId == groupId) {
+ if (mGroupId == groupId && mGroupInfo != null) {
+ mMemberInfoList.clear();
+ mMemberInfoList.addAll(mGroupInfo.getGroupMembers());
+ mChatDetailView.setMemberCount(" " + mMemberInfoList.size() + " 人");
refreshMemberList();
}
}
diff --git a/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java b/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java
index f0a03976..7d1c061e 100644
--- a/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java
+++ b/chatapp/src/main/java/jiguang/chat/controller/ChatItemController.java
@@ -13,7 +13,6 @@
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
-import android.os.Environment;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.view.View;
@@ -58,6 +57,7 @@
import cn.jpush.im.android.api.enums.ContentType;
import cn.jpush.im.android.api.enums.ConversationType;
import cn.jpush.im.android.api.enums.MessageDirect;
+import cn.jpush.im.android.api.model.ChatRoomInfo;
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.GroupInfo;
import cn.jpush.im.android.api.model.Message;
@@ -779,8 +779,29 @@ public void handleVideo(final Message msg, final ViewHolder holder, int position
FileContent fileContent = (FileContent) msg.getContent();
String videoPath = fileContent.getLocalPath();
if (videoPath != null) {
-// String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + msg.getServerMessageId();
- String thumbPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + msg.getServerMessageId();
+ File dir = new File(JGApplication.THUMP_PICTURE_DIR);
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+ String thumbPath;
+ if (msg.getServerMessageId() == 0) {
+ switch (msg.getTargetType()) {
+ case single:
+ thumbPath = dir + "/" + msg.getTargetType() + "_" + ((UserInfo) msg.getTargetInfo()).getUserID() + "_" + msg.getId();
+ break;
+ case group:
+ thumbPath = dir + "/" + msg.getTargetType() + "_" + ((GroupInfo) msg.getTargetInfo()).getGroupID() + "_" + msg.getId();
+ break;
+ case chatroom:
+ thumbPath = dir + "/" + msg.getTargetType() + "_" + ((ChatRoomInfo) msg.getTargetInfo()).getRoomID() + "_" + msg.getId();
+ break;
+ default:
+ Picasso.with(mContext).load(R.drawable.video_not_found).into(holder.picture);
+ return;
+ }
+ } else {
+ thumbPath = dir + "/" + msg.getServerMessageId();
+ }
String path = BitmapDecoder.extractThumbnail(videoPath, thumbPath);
setPictureScale(null, msg, path, holder.picture);
Picasso.with(mContext).load(new File(path)).into(holder.picture);
@@ -1014,7 +1035,9 @@ public void onProgressUpdate(double v) {
case receive_success:
holder.progressTv.setVisibility(View.GONE);
holder.contentLl.setBackground(mContext.getDrawable(R.drawable.jmui_msg_receive_bg));
- holder.fileLoad.setText("已下载");
+ if (mConv.getType() != ConversationType.chatroom) {
+ holder.fileLoad.setText("已下载");
+ }
break;
}
}
@@ -1063,6 +1086,13 @@ public void onComplete(int status, String desc, File file) {
public void handleGroupChangeMsg(Message msg, ViewHolder holder) {
+ String extraMsg = msg.getContent().getStringExtra("msg");
+ if (extraMsg != null) { // 聊天室通知事件消息
+ holder.groupChange.setText(extraMsg);
+ holder.groupChange.setVisibility(View.VISIBLE);
+ holder.msgTime.setVisibility(View.GONE);
+ return;
+ }
String content = ((EventNotificationContent) msg.getContent()).getEventText();
EventNotificationContent.EventNotificationType type = ((EventNotificationContent) msg
.getContent()).getEventNotificationType();
@@ -1071,6 +1101,8 @@ public void handleGroupChangeMsg(Message msg, ViewHolder holder) {
case group_member_exit:
case group_member_removed:
case group_info_updated:
+ case group_member_keep_silence:
+ case group_member_keep_silence_cancel:
holder.groupChange.setText(content);
holder.groupChange.setVisibility(View.VISIBLE);
holder.msgTime.setVisibility(View.GONE);
@@ -1089,10 +1121,14 @@ public void handleCustomMsg(Message msg, ViewHolder holder) {
CustomContent content = (CustomContent) msg.getContent();
Boolean isBlackListHint = content.getBooleanValue("blackList");
Boolean notFriendFlag = content.getBooleanValue("notFriend");
- if (isBlackListHint != null && isBlackListHint) {
- holder.groupChange.setText(R.string.jmui_server_803008);
- holder.groupChange.setVisibility(View.VISIBLE);
- } else {
+ //TODO:2019/04/09 会话列表滑动时自定义消息这里groupChange会出现null的情况
+ if (holder.groupChange != null) {
+ if (isBlackListHint != null && isBlackListHint) {
+ holder.groupChange.setText(R.string.jmui_server_803008);
+ holder.groupChange.setVisibility(View.VISIBLE);
+ } else {
+ holder.groupChange.setVisibility(View.GONE);
+ }
holder.groupChange.setVisibility(View.GONE);
}
@@ -1102,7 +1138,12 @@ public void handleCustomMsg(Message msg, ViewHolder holder) {
// } else {
// holder.groupChange.setVisibility(View.GONE);
// }
- holder.groupChange.setVisibility(View.GONE);
+ }
+
+ public void handleUnSupportMsg(Message msg, ViewHolder holder) {
+ if (holder.groupChange != null) {
+ holder.groupChange.setText(R.string.unsupported_msg);
+ }
}
public class BtnOrTxtListener implements View.OnClickListener {
@@ -1187,12 +1228,25 @@ public void onClick(View v) {
case image:
if (holder.picture != null && v.getId() == holder.picture.getId()) {
Intent intent = new Intent();
- intent.putExtra(JGApplication.TARGET_ID, mConv.getTargetId());
+ String targetId = "";
intent.putExtra("msgId", msg.getId());
- if (mConv.getType() == ConversationType.group) {
- GroupInfo groupInfo = (GroupInfo) mConv.getTargetInfo();
- intent.putExtra(JGApplication.GROUP_ID, groupInfo.getGroupID());
+ Object targetInfo = mConv.getTargetInfo();
+ switch (mConv.getType()) {
+ case single:
+ targetId = ((UserInfo) targetInfo).getUserName();
+ break;
+ case group:
+ targetId = String.valueOf(((GroupInfo) targetInfo).getGroupID());
+ break;
+ case chatroom:
+ targetId = String.valueOf(((ChatRoomInfo) targetInfo).getRoomID());
+ intent.putExtra(BrowserViewPagerActivity.MSG_JSON, msg.toJson());
+ intent.putExtra(BrowserViewPagerActivity.MSG_LIST_JSON, getImsgMsgListJson());
+ break;
+ default:
}
+ intent.putExtra(JGApplication.CONV_TYPE, mConv.getType());
+ intent.putExtra(JGApplication.TARGET_ID, targetId);
intent.putExtra(JGApplication.TARGET_APP_KEY, mConv.getTargetAppKey());
intent.putExtra("msgCount", mMsgList.size());
intent.putIntegerArrayListExtra(JGApplication.MsgIDs, getImgMsgIDList());
@@ -1454,6 +1508,16 @@ private ArrayList getImgMsgIDList() {
return imgMsgIDList;
}
+ private String getImsgMsgListJson() {
+ List messages = new ArrayList<>();
+ for (Message msg : mMsgList) {
+ if (msg.getContentType() == ContentType.image) {
+ messages.add(msg);
+ }
+ }
+ return Message.collectionToJson(messages);
+ }
+
private void browseDocument(String fileName, String path) {
try {
String ext = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
diff --git a/chatapp/src/main/java/jiguang/chat/controller/ChatRoomController.java b/chatapp/src/main/java/jiguang/chat/controller/ChatRoomController.java
new file mode 100644
index 00000000..9c702e4c
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/controller/ChatRoomController.java
@@ -0,0 +1,128 @@
+package jiguang.chat.controller;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.support.annotation.NonNull;
+import android.view.View;
+import android.widget.AdapterView;
+
+import com.scwang.smartrefresh.layout.api.RefreshLayout;
+import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener;
+import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import cn.jpush.im.android.api.ChatRoomManager;
+import cn.jpush.im.android.api.callback.RequestCallback;
+import cn.jpush.im.android.api.enums.ConversationType;
+import cn.jpush.im.android.api.model.ChatRoomInfo;
+import jiguang.chat.R;
+import jiguang.chat.activity.ChatActivity;
+import jiguang.chat.activity.SearchChatRoomActivity;
+import jiguang.chat.adapter.ChatRoomAdapter;
+import jiguang.chat.application.JGApplication;
+import jiguang.chat.utils.DialogCreator;
+import jiguang.chat.utils.HandleResponseCode;
+import jiguang.chat.view.ChatRoomView;
+
+/**
+ * Created by ${chenyn} on 2017/10/31.
+ */
+
+public class ChatRoomController implements AdapterView.OnItemClickListener, View.OnClickListener, OnRefreshListener, OnLoadMoreListener {
+ private ChatRoomView mChatRoomView;
+ private Context mContext;
+ private static final int PAGE_COUNT = 15;
+ private List chatRoomInfos = new ArrayList<>();
+ private ChatRoomAdapter chatRoomAdapter;
+
+ public ChatRoomController(ChatRoomView chatRoomView, Context context) {
+ this.mChatRoomView = chatRoomView;
+ this.mContext = context;
+ initChatRoomAdapter();
+ }
+
+ private void initChatRoomAdapter() {
+ Dialog loadingDialog = DialogCreator.createLoadingDialog(mContext, "正在加载...");
+ loadingDialog.show();
+ ChatRoomManager.getChatRoomListByApp(0, PAGE_COUNT, new RequestCallback>() {
+ @Override
+ public void gotResult(int i, String s, List result) {
+ loadingDialog.dismiss();
+ if (i == 0) {
+ chatRoomInfos.addAll(result);
+ } else {
+ HandleResponseCode.onHandle(mContext, i, false);
+ }
+ chatRoomAdapter = new ChatRoomAdapter(mContext, chatRoomInfos, mChatRoomView);
+ mChatRoomView.setChatRoomAdapter(chatRoomAdapter);
+ mChatRoomView.setNullChatRoom(chatRoomInfos.size() == 0);
+ }
+ });
+ }
+
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ Object itemAtPosition = parent.getItemAtPosition(position);
+ if (itemAtPosition != null && itemAtPosition instanceof ChatRoomInfo) {
+ ChatRoomInfo info = (ChatRoomInfo) itemAtPosition;
+ Intent intent = new Intent(mContext, ChatActivity.class);
+ intent.putExtra(JGApplication.CONV_TYPE, ConversationType.chatroom);
+ intent.putExtra("chatRoomId", info.getRoomID());
+ intent.putExtra("chatRoomName", info.getName());
+ mContext.startActivity(intent);
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.getId() == R.id.search_title) {
+ Intent intent = new Intent(mContext, SearchChatRoomActivity.class);
+ mContext.startActivity(intent);
+ }
+ }
+
+ @Override
+ public void onRefresh(@NonNull RefreshLayout refreshLayout) {
+ mChatRoomView.setNullChatRoom(false);
+ ChatRoomManager.getChatRoomListByApp(0, PAGE_COUNT, new RequestCallback>() {
+ @Override
+ public void gotResult(int i, String s, List result) {
+ if (i == 0) {
+ chatRoomInfos.clear();
+ chatRoomInfos.addAll(result);
+ mChatRoomView.setNullChatRoom(chatRoomInfos.size() == 0);
+ if (chatRoomAdapter != null) {
+ chatRoomAdapter.notifyDataSetChanged();
+ }
+ } else {
+ HandleResponseCode.onHandle(mContext, i, false);
+ }
+ refreshLayout.finishRefresh();
+ }
+ });
+ }
+
+ @Override
+ public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
+ mChatRoomView.setNullChatRoom(false);
+ ChatRoomManager.getChatRoomListByApp(chatRoomInfos.size(), PAGE_COUNT, new RequestCallback>() {
+ @Override
+ public void gotResult(int i, String s, List result) {
+ if (i == 0) {
+ chatRoomInfos.addAll(result);
+ mChatRoomView.setNullChatRoom(chatRoomInfos.size() == 0);
+ if (chatRoomAdapter != null) {
+ chatRoomAdapter.notifyDataSetChanged();
+ }
+ } else {
+ HandleResponseCode.onHandle(mContext, i, false);
+ }
+ refreshLayout.finishLoadMore();
+ }
+ });
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/controller/ContactsController.java b/chatapp/src/main/java/jiguang/chat/controller/ContactsController.java
index 203de349..434ac03a 100644
--- a/chatapp/src/main/java/jiguang/chat/controller/ContactsController.java
+++ b/chatapp/src/main/java/jiguang/chat/controller/ContactsController.java
@@ -5,6 +5,7 @@
import android.support.v4.app.FragmentActivity;
import android.text.TextUtils;
import android.view.View;
+import android.widget.TextView;
import com.activeandroid.ActiveAndroid;
@@ -17,10 +18,10 @@
import cn.jpush.im.android.api.callback.GetUserInfoListCallback;
import cn.jpush.im.android.api.model.UserInfo;
import jiguang.chat.R;
-import jiguang.chat.activity.FriendRecommendActivity;
import jiguang.chat.activity.GroupActivity;
import jiguang.chat.activity.SearchContactsActivity;
import jiguang.chat.activity.SearchForAddFriendActivity;
+import jiguang.chat.activity.VerificationMessageActivity;
import jiguang.chat.adapter.StickyListAdapter;
import jiguang.chat.application.JGApplication;
import jiguang.chat.database.FriendEntry;
@@ -39,12 +40,14 @@ public class ContactsController implements View.OnClickListener, SideBar.OnTouch
private Activity mContext;
private List mList = new ArrayList<>();
private StickyListAdapter mAdapter;
+ private TextView mAllContactNumber;
private List forDelete = new ArrayList<>();
public ContactsController(ContactsView mContactsView, FragmentActivity context) {
this.mContactsView = mContactsView;
this.mContext = context;
+ mAllContactNumber = mContext.findViewById(R.id.all_contact_number);
}
@@ -57,9 +60,11 @@ public void onClick(View v) {
mContext.startActivity(intent);
break;
case R.id.verify_ll://验证消息
- intent.setClass(mContext, FriendRecommendActivity.class);
+ //intent.setClass(mContext, FriendRecommendActivity.class);
+ intent.setClass(mContext, VerificationMessageActivity.class);
mContext.startActivity(intent);
mContactsView.dismissNewFriends();
+ mAllContactNumber.setVisibility(View.GONE);
break;
case R.id.group_ll://群组
intent.setClass(mContext, GroupActivity.class);
@@ -84,7 +89,7 @@ public void initContacts() {
public void gotResult(int responseCode, String responseMessage, List userInfoList) {
mContactsView.dismissLoadingHeader();
if (responseCode == 0) {
- if (userInfoList.size() != 0) {
+ if (userInfoList != null && userInfoList.size() != 0) {
mContactsView.dismissLine();
ActiveAndroid.beginTransaction();
try {
diff --git a/chatapp/src/main/java/jiguang/chat/controller/ConversationListController.java b/chatapp/src/main/java/jiguang/chat/controller/ConversationListController.java
index 49590e39..442ab72c 100644
--- a/chatapp/src/main/java/jiguang/chat/controller/ConversationListController.java
+++ b/chatapp/src/main/java/jiguang/chat/controller/ConversationListController.java
@@ -64,7 +64,8 @@ private void initConvListAdapter() {
SortConvList sortConvList = new SortConvList();
Collections.sort(mDatas, sortConvList);
for (Conversation con : mDatas) {
- if (con.getTargetId().equals("feedback_Android")) {
+ //如果会话有聊天室会话就把这会话删除
+ if (con.getTargetId().equals("feedback_Android") || con.getType().equals(ConversationType.chatroom)) {
delFeedBack.add(con);
}
if (!TextUtils.isEmpty(con.getExtra())) {
@@ -129,7 +130,7 @@ public void onItemClick(AdapterView> parent, View view, int position, long id)
mContext.getActivity().startActivity(intent);
return;
//单聊
- } else {
+ } else if (conv.getType() == ConversationType.single) {
String targetId = ((UserInfo) conv.getTargetInfo()).getUserName();
intent.putExtra(JGApplication.TARGET_ID, targetId);
intent.putExtra(JGApplication.TARGET_APP_KEY, conv.getTargetAppKey());
@@ -192,4 +193,7 @@ public void onClick(View v) {
}
return true;
}
+ public void delConversation() {
+ mDatas.remove(JGApplication.delConversation);
+ }
}
diff --git a/chatapp/src/main/java/jiguang/chat/controller/FriendInfoController.java b/chatapp/src/main/java/jiguang/chat/controller/FriendInfoController.java
index 745d1400..1b0afbe5 100644
--- a/chatapp/src/main/java/jiguang/chat/controller/FriendInfoController.java
+++ b/chatapp/src/main/java/jiguang/chat/controller/FriendInfoController.java
@@ -7,7 +7,6 @@
import jiguang.chat.R;
import jiguang.chat.activity.FriendInfoActivity;
import jiguang.chat.activity.FriendSettingActivity;
-import jiguang.chat.view.FriendInfoView;
/**
* Created by ${chenyn} on 2017/3/24.
@@ -16,9 +15,11 @@
public class FriendInfoController implements View.OnClickListener {
private FriendInfoActivity mContext;
private UserInfo friendInfo;
+ private int flags;
- public FriendInfoController(FriendInfoView friendInfoView, FriendInfoActivity context) {
+ public FriendInfoController(int flags, FriendInfoActivity context) {
this.mContext = context;
+ this.flags = flags;
}
@Override
@@ -31,7 +32,8 @@ public void onClick(View v) {
mContext.startBrowserAvatar();
break;
case R.id.jmui_commit_btn:
- Intent intent = new Intent(mContext, FriendSettingActivity.class);
+ Intent intent = new Intent();
+ intent.setClass(mContext, FriendSettingActivity.class);
intent.putExtra("userName", friendInfo.getUserName());
intent.putExtra("noteName", friendInfo.getNotename());
mContext.startActivity(intent);
diff --git a/chatapp/src/main/java/jiguang/chat/controller/MainController.java b/chatapp/src/main/java/jiguang/chat/controller/MainController.java
index de31ee54..acafdec8 100644
--- a/chatapp/src/main/java/jiguang/chat/controller/MainController.java
+++ b/chatapp/src/main/java/jiguang/chat/controller/MainController.java
@@ -9,6 +9,7 @@
import jiguang.chat.R;
import jiguang.chat.activity.MainActivity;
+import jiguang.chat.activity.fragment.ChatRoomFragment;
import jiguang.chat.activity.fragment.ContactsFragment;
import jiguang.chat.activity.fragment.ConversationListFragment;
import jiguang.chat.activity.fragment.MeFragment;
@@ -25,6 +26,7 @@ public class MainController implements View.OnClickListener, ViewPager.OnPageCha
private ConversationListFragment mConvListFragment;
private MeFragment mMeFragment;
private ContactsFragment mContactsFragment;
+ private ChatRoomFragment mChatRoomFragment;
public MainController(MainView mMainView, MainActivity context) {
@@ -37,10 +39,12 @@ private void setViewPager() {
final List fragments = new ArrayList<>();
// init Fragment
mConvListFragment = new ConversationListFragment();
+ mChatRoomFragment = new ChatRoomFragment();
mContactsFragment = new ContactsFragment();
mMeFragment = new MeFragment();
fragments.add(mConvListFragment);
+ fragments.add(mChatRoomFragment);
fragments.add(mContactsFragment);
fragments.add(mMeFragment);
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(mContext.getSupportFragmentManger(),
@@ -51,17 +55,19 @@ private void setViewPager() {
@Override
public void onClick(View v) {
- // TODO Auto-generated method stub
switch (v.getId()) {
case R.id.actionbar_msg_btn:
mMainView.setCurrentItem(0, false);
break;
- case R.id.actionbar_contact_btn:
+ case R.id.actionbar_chatroom_btn:
mMainView.setCurrentItem(1, false);
break;
- case R.id.actionbar_me_btn:
+ case R.id.actionbar_contact_btn:
mMainView.setCurrentItem(2, false);
break;
+ case R.id.actionbar_me_btn:
+ mMainView.setCurrentItem(3, false);
+ break;
}
}
diff --git a/chatapp/src/main/java/jiguang/chat/controller/MenuItemController.java b/chatapp/src/main/java/jiguang/chat/controller/MenuItemController.java
index e29e54ee..9659e0de 100644
--- a/chatapp/src/main/java/jiguang/chat/controller/MenuItemController.java
+++ b/chatapp/src/main/java/jiguang/chat/controller/MenuItemController.java
@@ -4,6 +4,7 @@
import android.view.View;
import jiguang.chat.R;
+import jiguang.chat.activity.SearchAddOpenGroupActivity;
import jiguang.chat.activity.CommonScanActivity;
import jiguang.chat.activity.CreateGroupActivity;
import jiguang.chat.activity.SearchForAddFriendActivity;
@@ -49,6 +50,11 @@ public void onClick(View v) {
intent.putExtra(Constant.REQUEST_SCAN_MODE, Constant.REQUEST_SCAN_MODE_QRCODE_MODE);
mFragment.getContext().startActivity(intent);
break;
+ //加入公开群
+ case R.id.add_open_group:
+ intent = new Intent(mFragment.getContext(), SearchAddOpenGroupActivity.class);
+ mFragment.getContext().startActivity(intent);
+ break;
default:
break;
}
diff --git a/chatapp/src/main/java/jiguang/chat/controller/SendFileController.java b/chatapp/src/main/java/jiguang/chat/controller/SendFileController.java
index d739069a..aadaf64e 100644
--- a/chatapp/src/main/java/jiguang/chat/controller/SendFileController.java
+++ b/chatapp/src/main/java/jiguang/chat/controller/SendFileController.java
@@ -15,6 +15,7 @@
import java.lang.ref.WeakReference;
import java.text.NumberFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -24,6 +25,7 @@
import cn.jpush.im.android.api.JMessageClient;
import cn.jpush.im.android.api.content.FileContent;
import cn.jpush.im.android.api.content.ImageContent;
+import cn.jpush.im.android.api.enums.ConversationType;
import cn.jpush.im.android.api.exceptions.JMFileSizeExceedException;
import cn.jpush.im.android.api.model.Conversation;
import cn.jpush.im.android.api.model.Message;
@@ -61,7 +63,7 @@ public class SendFileController implements View.OnClickListener, ViewPager.OnPag
private int mSize;
private final static int SEND_FILE = 0x4001;
private MyHandler myHandler = new MyHandler(this);
- private int[] mMsgIds;
+ private Message[] mMsgs;
public SendFileController(SendFileActivity context, SendFileView view) {
@@ -90,11 +92,17 @@ public SendFileController(SendFileActivity context, SendFileView view) {
String targetId = mContext.getIntent().getStringExtra(JGApplication.TARGET_ID);
String targetAppKey = mContext.getIntent().getStringExtra(JGApplication.TARGET_APP_KEY);
- long groupId = mContext.getIntent().getLongExtra(JGApplication.GROUP_ID, 0);
- if (groupId != 0) {
- mConv = JMessageClient.getGroupConversation(groupId);
- } else {
- mConv = JMessageClient.getSingleConversation(targetId, targetAppKey);
+ ConversationType convType = (ConversationType) mContext.getIntent().getSerializableExtra(JGApplication.CONV_TYPE);
+ switch (convType) {
+ case single:
+ mConv = JMessageClient.getSingleConversation(targetId, targetAppKey);
+ break;
+ case group:
+ mConv = JMessageClient.getGroupConversation(Long.valueOf(targetId));
+ break;
+ case chatroom:
+ mConv = JMessageClient.getChatRoomConversation(Long.valueOf(targetId));
+
}
}
@@ -144,7 +152,7 @@ public void onClick(View view) {
mDialog.setMessage(mContext.getString(R.string.sending_hint));
mDialog.show();
Iterator>> iterator = mFileMap.entrySet().iterator();
- mMsgIds = new int[mSize];
+ mMsgs = new Message[mSize];
while (iterator.hasNext()) {
final Map.Entry> entry = iterator.next();
ArrayList list = entry.getValue();
@@ -159,9 +167,9 @@ public void onClick(View view) {
public void gotResult(int status, String desc, ImageContent imageContent) {
if (status == 0) {
Message msg = mConv.createSendMessage(imageContent);
- mMsgIds[mIndex.get()] = msg.getId();
+ mMsgs[mIndex.get()] = msg;
} else {
- mMsgIds[mIndex.get()] = -1;
+ mMsgs[mIndex.get()] = null;
}
mIndex.incrementAndGet();
if (mIndex.get() >= mSize) {
@@ -176,9 +184,9 @@ public void gotResult(int status, String desc, ImageContent imageContent) {
public void gotResult(int status, String desc, ImageContent imageContent) {
if (status == 0) {
Message msg = mConv.createSendMessage(imageContent);
- mMsgIds[mIndex.get()] = msg.getId();
+ mMsgs[mIndex.get()] = msg;
} else {
- mMsgIds[mIndex.get()] = -1;
+ mMsgs[mIndex.get()] = null;
}
mIndex.incrementAndGet();
if (mIndex.get() >= mSize) {
@@ -204,7 +212,7 @@ public void gotResult(int status, String desc, ImageContent imageContent) {
content.setNumberExtra("fileSize", file.length());
Message msg = mConv.createSendMessage(content);
if (mIndex.get() < mSize) {
- mMsgIds[mIndex.get()] = msg.getId();
+ mMsgs[mIndex.get()] = msg;
mIndex.incrementAndGet();
if (mIndex.get() >= mSize) {
myHandler.sendEmptyMessage(SEND_FILE);
@@ -310,7 +318,7 @@ public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case SEND_FILE:
Intent intent = new Intent();
- intent.putExtra(JGApplication.MsgIDs, controller.mMsgIds);
+ intent.putExtra(JGApplication.MSG_LIST_JSON, Message.collectionToJson(Arrays.asList(controller.mMsgs)));
controller.mContext.setResult(JGApplication.RESULT_CODE_SEND_FILE, intent);
if (controller.mDialog != null) {
controller.mDialog.dismiss();
diff --git a/chatapp/src/main/java/jiguang/chat/database/ConversationEntry.java b/chatapp/src/main/java/jiguang/chat/database/ConversationEntry.java
deleted file mode 100644
index 1dc5aacf..00000000
--- a/chatapp/src/main/java/jiguang/chat/database/ConversationEntry.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package jiguang.chat.database;
-
-/**
- * Created by ${chenyn} on 2017/7/18.
- */
-
-import com.activeandroid.Model;
-import com.activeandroid.annotation.Column;
-import com.activeandroid.annotation.Table;
-import com.activeandroid.query.Select;
-
-@Table(name = "conversation", id = "_id")
-public class ConversationEntry extends Model{
-
- @Column(name = "Targetname")
- public String targetname;
-
- @Column(name = "Orders")
- public Integer order;
-
-
- public ConversationEntry(){
- super();
- }
-
- public ConversationEntry(String targetname, int order) {
- super();
- this.targetname = targetname;
- this.order = order;
- }
-
- public static ConversationEntry getTopConversation(int order) {
- return new Select().from(ConversationEntry.class)
- .where("Orders = ?", order).executeSingle();
- }
-}
diff --git a/chatapp/src/main/java/jiguang/chat/database/GroupApplyEntry.java b/chatapp/src/main/java/jiguang/chat/database/GroupApplyEntry.java
new file mode 100644
index 00000000..f03d84b7
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/database/GroupApplyEntry.java
@@ -0,0 +1,91 @@
+package jiguang.chat.database;
+
+/**
+ * Created by ${chenyn} on 2017/7/18.
+ */
+
+import com.activeandroid.Model;
+import com.activeandroid.annotation.Column;
+import com.activeandroid.annotation.Table;
+import com.activeandroid.query.Delete;
+import com.activeandroid.query.Select;
+
+@Table(name = "group_apply", id = "_id")
+public class GroupApplyEntry extends Model {
+
+ @Column(name = "FromUsername")
+ public String fromUsername;
+
+ @Column(name = "ToUsername")
+ public String toUsername;
+
+ @Column(name = "AppKey")
+ public String appKey;
+
+ @Column(name = "Avatar")
+ public String Avatar;
+
+ @Column(name = "FromDisplayName")
+ public String fromDisplayName;
+
+ @Column(name = "toDisplayName")
+ public String toDisplayName;
+
+ @Column(name = "Reason")
+ public String reason;
+
+ @Column(name = "State")
+ public String state;
+
+ @Column(name = "EventJson")
+ public String eventJson;
+
+ @Column(name = "GroupName")
+ public String groupName;
+
+ @Column(name = "User")
+ public UserEntry user;
+
+ @Column(name = "BtnState")
+ public int btnState;
+
+ @Column(name = "GroupType")
+ public int groupType;
+
+ public GroupApplyEntry() {
+ super();
+ }
+
+ public GroupApplyEntry(String fromUsername, String toUsername, String appKey, String Avatar, String fromDisplayName, String toDisplayName,
+ String reason, String state, String eventJson, String groupName, UserEntry user, int btnState, int groupType) {
+ super();
+ this.fromUsername = fromUsername;
+ this.toUsername = toUsername;
+ this.appKey = appKey;
+ this.Avatar = Avatar;
+ this.fromDisplayName = fromDisplayName;
+ this.toDisplayName = toDisplayName;
+ this.reason = reason;
+ this.state = state;
+ this.eventJson = eventJson;
+ this.groupName = groupName;
+ this.user = user;
+ this.btnState = btnState;
+ this.groupType = groupType;
+ }
+
+ public static GroupApplyEntry getEntry(UserEntry user, String username, String appKey) {
+ return new Select().from(GroupApplyEntry.class).where("ToUsername = ?", username)
+ .where("AppKey = ?", appKey)
+ .where("User = ?", user.getId()).executeSingle();
+ }
+
+ public static GroupApplyEntry getEntry(long id) {
+ return new Select().from(GroupApplyEntry.class).where("_id = ?", id).executeSingle();
+ }
+
+ public static void deleteEntry(GroupApplyEntry entry) {
+ new Delete().from(GroupApplyEntry.class).where("_id = ?", entry.getId()).execute();
+ }
+
+}
diff --git a/chatapp/src/main/java/jiguang/chat/database/RefuseGroupEntry.java b/chatapp/src/main/java/jiguang/chat/database/RefuseGroupEntry.java
new file mode 100644
index 00000000..19e532d8
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/database/RefuseGroupEntry.java
@@ -0,0 +1,52 @@
+package jiguang.chat.database;
+
+import com.activeandroid.Model;
+import com.activeandroid.annotation.Column;
+import com.activeandroid.annotation.Table;
+import com.activeandroid.query.Select;
+
+/**
+ * Created by ${chenyn} on 2017/11/24.
+ */
+
+@Table(name = "refuse_group", id = "_id")
+public class RefuseGroupEntry extends Model {
+
+ @Column(name = "Username")
+ public String username;
+
+ @Column(name = "DisplayName")
+ public String displayName;
+
+ @Column(name = "GroupId")
+ public String groupId;
+
+ @Column(name = "AppKey")
+ public String appKey;
+
+ @Column(name = "Avatar")
+ public String avatar;
+
+ @Column(name = "User")
+ public UserEntry user;
+
+ public RefuseGroupEntry() {}
+
+ public RefuseGroupEntry(UserEntry user, String username, String displayName, String groupId, String appKey, String avatar) {
+ super();
+ this.user = user;
+ this.username = username;
+ this.displayName = displayName;
+ this.groupId = groupId;
+ this.appKey = appKey;
+ this.avatar = avatar;
+ }
+
+ public static RefuseGroupEntry getEntry(UserEntry user, String username, String appKey) {
+ return new Select().from(RefuseGroupEntry.class).where("Username = ?", username)
+ .where("AppKey = ?", appKey)
+ .where("User = ?", user.getId()).executeSingle();
+ }
+
+
+}
diff --git a/chatapp/src/main/java/jiguang/chat/database/UserEntry.java b/chatapp/src/main/java/jiguang/chat/database/UserEntry.java
index fb12073a..d01247e4 100644
--- a/chatapp/src/main/java/jiguang/chat/database/UserEntry.java
+++ b/chatapp/src/main/java/jiguang/chat/database/UserEntry.java
@@ -36,6 +36,14 @@ public List getRecommends() {
return getMany(FriendRecommendEntry.class, "User");
}
+ public List getGroupApplyRecommends() {
+ return getMany(GroupApplyEntry.class, "User");
+ }
+
+ public List getRefuseGroupRecommends() {
+ return getMany(RefuseGroupEntry.class, "User");
+ }
+
public List getFriends() {
return getMany(FriendEntry.class, "User");
}
diff --git a/chatapp/src/main/java/jiguang/chat/entity/GroupApplyInvitation.java b/chatapp/src/main/java/jiguang/chat/entity/GroupApplyInvitation.java
new file mode 100644
index 00000000..9100b406
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/entity/GroupApplyInvitation.java
@@ -0,0 +1,21 @@
+package jiguang.chat.entity;
+
+public enum GroupApplyInvitation {
+ ACCEPTED("accepted"),//已接受
+ INVITING("inviting"),
+ INVITED("invited"),
+ REFUSED("refused"),
+ BE_REFUSED("be_refused"),
+ DEFAULT("default");
+
+
+ private String value;
+
+ GroupApplyInvitation(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/location/activity/MapPickerActivity.java b/chatapp/src/main/java/jiguang/chat/location/activity/MapPickerActivity.java
index 7f149ac3..83e3f1c6 100755
--- a/chatapp/src/main/java/jiguang/chat/location/activity/MapPickerActivity.java
+++ b/chatapp/src/main/java/jiguang/chat/location/activity/MapPickerActivity.java
@@ -50,6 +50,7 @@
import java.util.UUID;
import cn.jpush.im.android.api.JMessageClient;
+import cn.jpush.im.android.api.enums.ConversationType;
import cn.jpush.im.android.api.model.Conversation;
import jiguang.chat.R;
import jiguang.chat.application.JGApplication;
@@ -123,14 +124,23 @@ protected void onCreate(Bundle savedInstanceState) {
initMap();
initIntent();
+ ConversationType convType = (ConversationType) getIntent().getSerializableExtra(JGApplication.CONV_TYPE);
String targetId = getIntent().getStringExtra(JGApplication.TARGET_ID);
String targetAppKey = getIntent().getStringExtra(JGApplication.TARGET_APP_KEY);
- long groupId = getIntent().getLongExtra(JGApplication.GROUP_ID, 0);
-
- if (groupId != 0) {
- conv = JMessageClient.getGroupConversation(groupId);
- } else {
- conv = JMessageClient.getSingleConversation(targetId, targetAppKey);
+ if (convType != null) {
+ switch (convType) {
+ case single:
+ conv = JMessageClient.getSingleConversation(targetId, targetAppKey);
+ break;
+ case group:
+ conv = JMessageClient.getGroupConversation(Long.valueOf(targetId));
+ break;
+ case chatroom:
+ conv = JMessageClient.getChatRoomConversation(Long.valueOf(targetId));
+ break;
+ default:
+ break;
+ }
}
diff --git a/chatapp/src/main/java/jiguang/chat/utils/DialogCreator.java b/chatapp/src/main/java/jiguang/chat/utils/DialogCreator.java
index 036605dd..1d24401d 100644
--- a/chatapp/src/main/java/jiguang/chat/utils/DialogCreator.java
+++ b/chatapp/src/main/java/jiguang/chat/utils/DialogCreator.java
@@ -19,6 +19,8 @@
import android.widget.TextView;
import android.widget.Toast;
+import org.greenrobot.eventbus.EventBus;
+
import cn.jpush.im.android.api.JMessageClient;
import cn.jpush.im.android.api.content.FileContent;
import cn.jpush.im.android.api.content.ImageContent;
@@ -30,7 +32,6 @@
import cn.jpush.im.android.api.model.Message;
import cn.jpush.im.android.api.model.UserInfo;
import cn.jpush.im.android.api.options.MessageSendingOptions;
-import cn.jpush.im.android.eventbus.EventBus;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.application.JGApplication;
diff --git a/chatapp/src/main/java/jiguang/chat/utils/FileHelper.java b/chatapp/src/main/java/jiguang/chat/utils/FileHelper.java
index fe94a01b..ebafa2af 100644
--- a/chatapp/src/main/java/jiguang/chat/utils/FileHelper.java
+++ b/chatapp/src/main/java/jiguang/chat/utils/FileHelper.java
@@ -73,7 +73,6 @@ public void run() {
destDir.mkdirs();
}
final File tempFile = new File(JGApplication.FILE_DIR + fileName);
- System.out.println("=================" + tempFile.exists() + tempFile.isFile());
FileOutputStream fos = new FileOutputStream(tempFile);
byte[] bt = new byte[1024];
int c;
diff --git a/chatapp/src/main/java/jiguang/chat/utils/GroupMemberListComparator.java b/chatapp/src/main/java/jiguang/chat/utils/GroupMemberListComparator.java
new file mode 100644
index 00000000..fae3fb78
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/utils/GroupMemberListComparator.java
@@ -0,0 +1,49 @@
+package jiguang.chat.utils;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+
+import cn.jpush.im.android.api.model.UserInfo;
+import jiguang.chat.utils.pinyin.HanziToPinyin;
+
+/**
+ * Created by ${chenyn} on 2017/11/3.
+ */
+
+public class GroupMemberListComparator implements Comparator{
+ @Override
+ public int compare(UserInfo o1, UserInfo o2) {
+ if (getLetter(o1.getDisplayName()).equals("@") ||
+ getLetter(o2.getDisplayName()).equals("#")) {
+ return -1;
+ }else if (getLetter(o1.getDisplayName()).equals("#")
+ || getLetter(o2.getDisplayName()).equals("@")) {
+ return 1;
+ }else {
+ return getLetter(o1.getDisplayName()).compareTo(getLetter(o2.getDisplayName()));
+ }
+ }
+
+ public String getLetter(String name) {
+ String letter;
+ ArrayList tokens = HanziToPinyin.getInstance()
+ .get(name);
+ StringBuilder sb = new StringBuilder();
+ if (tokens != null && tokens.size() > 0) {
+ for (HanziToPinyin.Token token : tokens) {
+ if (token.type == HanziToPinyin.Token.PINYIN) {
+ sb.append(token.target);
+ } else {
+ sb.append(token.source);
+ }
+ }
+ }
+ String sortString = sb.toString().substring(0, 1).toUpperCase();
+ if (sortString.matches("[A-Z]")) {
+ letter = sortString.toUpperCase();
+ } else {
+ letter = "#";
+ }
+ return letter;
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/utils/ThreadUtil.java b/chatapp/src/main/java/jiguang/chat/utils/ThreadUtil.java
index 0cc8b97c..5650735c 100644
--- a/chatapp/src/main/java/jiguang/chat/utils/ThreadUtil.java
+++ b/chatapp/src/main/java/jiguang/chat/utils/ThreadUtil.java
@@ -2,13 +2,14 @@
import android.os.Handler;
+import android.os.Looper;
/**
* Created by ${chenyn} on 2017/3/10.
*/
public class ThreadUtil {
- static Handler mHandler = new Handler();
+ static Handler mHandler = new Handler(Looper.getMainLooper());
public static void runInThread(Runnable task) {
new Thread(task).start();
diff --git a/chatapp/src/main/java/jiguang/chat/utils/photochoose/ChoosePhoto.java b/chatapp/src/main/java/jiguang/chat/utils/photochoose/ChoosePhoto.java
index e88ab9a9..268be69e 100644
--- a/chatapp/src/main/java/jiguang/chat/utils/photochoose/ChoosePhoto.java
+++ b/chatapp/src/main/java/jiguang/chat/utils/photochoose/ChoosePhoto.java
@@ -16,6 +16,7 @@
import cn.jpush.im.android.api.model.GroupInfo;
import cn.jpush.im.api.BasicCallback;
import jiguang.chat.activity.PersonalActivity;
+import jiguang.chat.application.JGApplication;
import jiguang.chat.utils.HandleResponseCode;
import jiguang.chat.utils.SharePreferenceManager;
import jiguang.chat.utils.ToastUtil;
@@ -137,4 +138,19 @@ public void onPhotoCancel() {
});
}
+ public void getCreateGroupAvatar(ImageView iv_groupAvatar) {
+ photoUtils = new PhotoUtils(new PhotoUtils.OnPhotoResultListener() {
+ @Override
+ public void onPhotoResult(Uri uri) {
+ iv_groupAvatar.setImageBitmap(BitmapFactory.decodeFile(uri.getPath()));
+ JGApplication.groupAvatarPath = uri.getPath();
+ }
+
+ @Override
+ public void onPhotoCancel() {
+
+ }
+ });
+ }
+
}
diff --git a/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/camera/CameraManager.java b/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/camera/CameraManager.java
index 91435b90..91edf647 100755
--- a/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/camera/CameraManager.java
+++ b/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/camera/CameraManager.java
@@ -1,503 +1,506 @@
-package jiguang.chat.utils.photovideo.takevideo.camera;
-
-import android.app.Application;
-import android.content.Context;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera;
-import android.media.CamcorderProfile;
-import android.media.MediaRecorder;
-import android.widget.Toast;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import jiguang.chat.utils.photovideo.takevideo.utils.LogUtils;
-
-
-/**
- * 相机管理类
- */
-
-public final class CameraManager {
-
- private Application context;
- /**
- * camera
- */
- private Camera mCamera;
- /**
- * 视频录制
- */
- private MediaRecorder mMediaRecorder;
- /**
- * 相机闪光状态
- */
- private int cameraFlash;
- /**
- * 前后置状态
- */
- private int cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;
- /**
- * 是否支持前置摄像,是否支持闪光
- */
- private boolean isSupportFrontCamera, isSupportFlashCamera;
- /**
- * 录制视频的相关参数
- */
- private CamcorderProfile mProfile;
- /**
- * 0为拍照, 1为录像
- */
- private int cameraType;
-
- private CameraManager(Application context) {
- this.context = context;
- isSupportFrontCamera = CameraUtils.isSupportFrontCamera();
- isSupportFlashCamera = CameraUtils.isSupportFlashCamera(context);
- if (isSupportFrontCamera) {
- cameraFacing = CameraUtils.getCameraFacing(context, Camera.CameraInfo.CAMERA_FACING_BACK);
- }
- if (isSupportFlashCamera) {
- cameraFlash = CameraUtils.getCameraFlash(context);
- }
- }
-
- private static CameraManager INSTANCE;
-
- public static CameraManager getInstance(Application context) {
- if (INSTANCE == null) {
- synchronized (CameraManager.class) {
- if (INSTANCE == null) {
- INSTANCE = new CameraManager(context);
- }
- }
- }
- return INSTANCE;
- }
-
- /**
- * 打开camera
- */
- public void openCamera(Context context, SurfaceTexture surfaceTexture, int width, int height) {
- if (mCamera == null) {
- try {
- mCamera = Camera.open(cameraFacing);//打开当前选中的摄像头
- mProfile = CamcorderProfile.get(cameraFacing, CamcorderProfile.QUALITY_HIGH);
- mCamera.setDisplayOrientation(90);//默认竖直拍照
- mCamera.setPreviewTexture(surfaceTexture);
- initCameraParameters(cameraFacing, width, height);
- mCamera.startPreview();
- } catch (Exception e) {
- if (mCamera != null) {
- mCamera.release();
- mCamera = null;
- }
- }
- }
- }
-
-
- /**
- * 开启预览,前提是camera初始化了
- */
- public void restartPreview() {
- if (mCamera == null) return;
- try {
- Camera.Parameters parameters = mCamera.getParameters();
- int zoom = parameters.getZoom();
- if (zoom > 0) {
- parameters.setZoom(0);
- mCamera.setParameters(parameters);
- }
- mCamera.startPreview();
- } catch (Exception e) {
- LogUtils.i(e);
- if (mCamera != null) {
- mCamera.release();
- mCamera = null;
- }
- }
- }
-
- private void initCameraParameters(int cameraId, int width, int height) {
- Camera.Parameters parameters = mCamera.getParameters();
- if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
- List focusModes = parameters.getSupportedFocusModes();
- if (focusModes != null) {
- if (cameraType == 0) {
- if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
- parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
- }
- } else {
- if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
- parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
- }
- }
- }
- }
- parameters.setRotation(90);//设置旋转代码,
- switch (cameraFlash) {
- case 0:
- parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
- break;
- case 1:
- parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
- break;
- case 2:
- parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
- break;
- }
- List pictureSizes = parameters.getSupportedPictureSizes();
- List previewSizes = parameters.getSupportedPreviewSizes();
- if (!isEmpty(pictureSizes) && !isEmpty(previewSizes)) {
- /*for (Camera.Size size : pictureSizes) {
- LogUtils.i("pictureSize " + size.width + " " + size.height);
- }
- for (Camera.Size size : pictureSizes) {
- LogUtils.i("previewSize " + size.width + " " + size.height);
- }*/
- Camera.Size optimalPicSize = getOptimalSize(pictureSizes, width, height);
- Camera.Size optimalPreSize = getOptimalSize(previewSizes, width, height);
- LogUtils.i("TextureSize " + width + " " + height + " optimalSize pic " + optimalPicSize.width + " " + optimalPicSize.height + " pre " + optimalPreSize.width + " " + optimalPreSize.height);
- parameters.setPictureSize(optimalPicSize.width, optimalPicSize.height);
- parameters.setPreviewSize(optimalPreSize.width, optimalPreSize.height);
- mProfile.videoFrameWidth = optimalPreSize.width;
- mProfile.videoFrameHeight = optimalPreSize.height;
- mProfile.videoBitRate = 5000000;//此参数主要决定视频拍出大小
- }
- mCamera.setParameters(parameters);
- }
-
- /**
- * 释放摄像头
- */
- public void closeCamera() {
- this.cameraType = 0;
- if (mCamera != null) {
- try {
- mCamera.stopPreview();
- mCamera.release();
- mCamera = null;
- } catch (Exception e) {
- LogUtils.i(e);
- if (mCamera != null) {
- mCamera.release();
- mCamera = null;
- }
- }
- }
- }
-
- /**
- * 集合不为空
- *
- * @param list
- * @param
- * @return
- */
- private boolean isEmpty(List list) {
- return list == null || list.isEmpty();
- }
-
- /**
- * 获取最佳预览相机Size参数
- *
- * @return
- */
- private Camera.Size getOptimalSize(List sizes, int w, int h) {
- Camera.Size optimalSize = null;
- float targetRadio = h / (float) w;
- float optimalDif = Float.MAX_VALUE; //最匹配的比例
- int optimalMaxDif = Integer.MAX_VALUE;//最优的最大值差距
- for (Camera.Size size : sizes) {
- float newOptimal = size.width / (float) size.height;
- float newDiff = Math.abs(newOptimal - targetRadio);
- if (newDiff < optimalDif) { //更好的尺寸
- optimalDif = newDiff;
- optimalSize = size;
- optimalMaxDif = Math.abs(h - size.width);
- } else if (newDiff == optimalDif) {//更好的尺寸
- int newOptimalMaxDif = Math.abs(h - size.width);
- if (newOptimalMaxDif < optimalMaxDif) {
- optimalDif = newDiff;
- optimalSize = size;
- optimalMaxDif = newOptimalMaxDif;
- }
- }
- }
- return optimalSize;
- }
-
- /**
- * 缩放
- *
- * @param isZoomIn
- */
- public void handleZoom(boolean isZoomIn) {
- if (mCamera == null) return;
- Camera.Parameters params = mCamera.getParameters();
- if (params == null) return;
- if (params.isZoomSupported()) {
- int maxZoom = params.getMaxZoom();
- int zoom = params.getZoom();
- if (isZoomIn && zoom < maxZoom) {
- zoom++;
- } else if (zoom > 0) {
- zoom--;
- }
- params.setZoom(zoom);
- mCamera.setParameters(params);
- } else {
- LogUtils.i("zoom not supported");
- }
- }
-
- /**
- * 更换前后置摄像
- */
- public void changeCameraFacing(Context context, SurfaceTexture surfaceTexture, int width, int height) {
- if (isSupportFrontCamera) {
- Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
- int cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数
- for (int i = 0; i < cameraCount; i++) {
- Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
- if (cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) { //现在是后置,变更为前置
- if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位为前置
- closeCamera();
- cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;
- CameraUtils.setCameraFacing(context, cameraFacing);
- openCamera(context, surfaceTexture, width, height);
- break;
- }
- } else {//现在是前置, 变更为后置
- if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位
- closeCamera();
- cameraFacing = Camera.CameraInfo.CAMERA_FACING_FRONT;
- CameraUtils.setCameraFacing(context, cameraFacing);
- openCamera(context, surfaceTexture, width, height);
- break;
- }
- }
- }
- } else { //不支持摄像机
- Toast.makeText(context, "您的手机不支持前置摄像", Toast.LENGTH_SHORT).show();
- }
- }
-
- /**
- * 改变闪光状态
- */
- public void changeCameraFlash(SurfaceTexture surfaceTexture, int width, int height) {
- if (!isSupportFlashCamera) {
- Toast.makeText(context, "您的手机不支闪光", Toast.LENGTH_SHORT).show();
- return;
- }
- if (mCamera != null) {
- Camera.Parameters parameters = mCamera.getParameters();
- if (parameters != null) {
- int newState = cameraFlash;
- switch (cameraFlash) {
- case 0: //自动
- parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
- newState = 1;
- break;
- case 1://open
- parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
- newState = 2;
- break;
- case 2: //close
- parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
- newState = 0;
- break;
- }
- cameraFlash = newState;
- CameraUtils.setCameraFlash(context, newState);
- mCamera.setParameters(parameters);
- }
- }
- }
-
- /**
- * 拍照
- */
- public void takePhoto(Camera.PictureCallback callback) {
- if (mCamera != null) {
- try {
- mCamera.takePicture(null, null, callback);
- } catch (Exception e) {
- Toast.makeText(context, "拍摄失败", Toast.LENGTH_SHORT).show();
- }
- }
- }
-
-
- /**
- * 开始录制视频
- */
- public void startMediaRecord(String savePath) {
- if (mCamera == null || mProfile == null) return;
- mCamera.unlock();
- if (mMediaRecorder == null) {
- mMediaRecorder = new MediaRecorder();
- mMediaRecorder.setOrientationHint(90);
- }
- if (isCameraFrontFacing()) {
- mMediaRecorder.setOrientationHint(270);
- }
- mMediaRecorder.reset();
- mMediaRecorder.setCamera(mCamera);
- mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
- mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
- mMediaRecorder.setProfile(mProfile);
- mMediaRecorder.setOutputFile(savePath);
- try {
- mMediaRecorder.prepare();
- mMediaRecorder.start();
- } catch (Exception e) {
- e.printStackTrace();
-
- }
- }
-
- /**
- * 停止录制
- */
- public void stopMediaRecord() {
- this.cameraType = 0;
- stopRecorder();
- releaseMediaRecorder();
- }
-
- private void releaseMediaRecorder() {
- if (mMediaRecorder != null) {
- try {
- mMediaRecorder.reset();
- mMediaRecorder.release();
- mMediaRecorder = null;
- mCamera.lock();
- } catch (Exception e) {
- e.printStackTrace();
- LogUtils.i(e);
- }
- }
- }
-
- private void stopRecorder() {
- if (mMediaRecorder != null) {
- try {
- mMediaRecorder.stop();
- } catch (Exception e) {
- e.printStackTrace();
- LogUtils.i(e);
- }
-
- }
- }
-
- public boolean isSupportFrontCamera() {
- return isSupportFrontCamera;
- }
-
- public boolean isSupportFlashCamera() {
- return isSupportFlashCamera;
- }
-
- public boolean isCameraFrontFacing() {
- return cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT;
- }
-
- /**
- * 设置对焦类型
- *
- * @param cameraType
- */
- public void setCameraType(int cameraType) {
- this.cameraType = cameraType;
- if (mCamera != null) {//拍摄视频时
- if (cameraFacing == Camera.CameraInfo.CAMERA_FACING_BACK) {
- Camera.Parameters parameters = mCamera.getParameters();
- List focusModes = parameters.getSupportedFocusModes();
- if (focusModes != null) {
- if (cameraType == 0) {
- if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
- parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
- }
- } else {
- if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
- parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
- }
- }
- }
- }
- }
- }
-
- public int getCameraFlash() {
- return cameraFlash;
- }
-
- /**
- * 对焦
- *
- * @param x
- * @param y
- */
- public void handleFocusMetering(float x, float y) {
- Camera.Parameters params = mCamera.getParameters();
- Camera.Size previewSize = params.getPreviewSize();
- Rect focusRect = calculateTapArea(x, y, 1f, previewSize);
- Rect meteringRect = calculateTapArea(x, y, 1.5f, previewSize);
- mCamera.cancelAutoFocus();
-
- if (params.getMaxNumFocusAreas() > 0) {
- List focusAreas = new ArrayList<>();
- focusAreas.add(new Camera.Area(focusRect, 1000));
- params.setFocusAreas(focusAreas);
- } else {
- LogUtils.i("focus areas not supported");
- }
- if (params.getMaxNumMeteringAreas() > 0) {
- List meteringAreas = new ArrayList<>();
- meteringAreas.add(new Camera.Area(meteringRect, 1000));
- params.setMeteringAreas(meteringAreas);
- } else {
- LogUtils.i("metering areas not supported");
- }
- final String currentFocusMode = params.getFocusMode();
- params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
- mCamera.setParameters(params);
-
- mCamera.autoFocus(new Camera.AutoFocusCallback() {
- @Override
- public void onAutoFocus(boolean success, Camera camera) {
- Camera.Parameters params = camera.getParameters();
- params.setFocusMode(currentFocusMode);
- camera.setParameters(params);
- }
- });
- }
-
- private Rect calculateTapArea(float x, float y, float coefficient, Camera.Size previewSize) {
- float focusAreaSize = 300;
- int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();
- int centerX = (int) (x / previewSize.width - 1000);
- int centerY = (int) (y / previewSize.height - 1000);
- int left = clamp(centerX - areaSize / 2, -1000, 1000);
- int top = clamp(centerY - areaSize / 2, -1000, 1000);
- RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
- return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom));
- }
-
- private int clamp(int x, int min, int max) {
- if (x > max) {
- return max;
- }
- if (x < min) {
- return min;
- }
- return x;
- }
-
-}
+package jiguang.chat.utils.photovideo.takevideo.camera;
+
+import android.app.Application;
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.SurfaceTexture;
+import android.hardware.Camera;
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jiguang.chat.utils.photovideo.takevideo.utils.LogUtils;
+
+
+/**
+ * 相机管理类
+ */
+
+public final class CameraManager {
+
+ private Application context;
+ /**
+ * camera
+ */
+ private Camera mCamera;
+ /**
+ * 视频录制
+ */
+ private MediaRecorder mMediaRecorder;
+ /**
+ * 相机闪光状态
+ */
+ private int cameraFlash;
+ /**
+ * 前后置状态
+ */
+ private int cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;
+ /**
+ * 是否支持前置摄像,是否支持闪光
+ */
+ private boolean isSupportFrontCamera, isSupportFlashCamera;
+ /**
+ * 录制视频的相关参数
+ */
+ private CamcorderProfile mProfile;
+ /**
+ * 0为拍照, 1为录像
+ */
+ private int cameraType;
+
+ private CameraManager(Application context) {
+ this.context = context;
+ isSupportFrontCamera = CameraUtils.isSupportFrontCamera();
+ isSupportFlashCamera = CameraUtils.isSupportFlashCamera(context);
+ if (isSupportFrontCamera) {
+ cameraFacing = CameraUtils.getCameraFacing(context, Camera.CameraInfo.CAMERA_FACING_BACK);
+ }
+ if (isSupportFlashCamera) {
+ cameraFlash = CameraUtils.getCameraFlash(context);
+ }
+ }
+
+ private static CameraManager INSTANCE;
+
+ public static CameraManager getInstance(Application context) {
+ if (INSTANCE == null) {
+ synchronized (CameraManager.class) {
+ if (INSTANCE == null) {
+ INSTANCE = new CameraManager(context);
+ }
+ }
+ }
+ return INSTANCE;
+ }
+
+ /**
+ * 打开camera
+ */
+ public void openCamera(Context context, SurfaceTexture surfaceTexture, int width, int height) {
+ if (mCamera == null) {
+ try {
+ mCamera = Camera.open(cameraFacing);//打开当前选中的摄像头
+ mProfile = CamcorderProfile.get(cameraFacing, CamcorderProfile.QUALITY_HIGH);
+ mCamera.setDisplayOrientation(90);//默认竖直拍照
+ mCamera.setPreviewTexture(surfaceTexture);
+ initCameraParameters(cameraFacing, width, height);
+ mCamera.startPreview();
+ } catch (Exception e) {
+ if (mCamera != null) {
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * 开启预览,前提是camera初始化了
+ */
+ public void restartPreview() {
+ if (mCamera == null) return;
+ try {
+ Camera.Parameters parameters = mCamera.getParameters();
+ int zoom = parameters.getZoom();
+ if (zoom > 0) {
+ parameters.setZoom(0);
+ mCamera.setParameters(parameters);
+ }
+ mCamera.startPreview();
+ } catch (Exception e) {
+ LogUtils.i(e);
+ if (mCamera != null) {
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+ }
+
+ private void initCameraParameters(int cameraId, int width, int height) {
+ Camera.Parameters parameters = mCamera.getParameters();
+ if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
+ List focusModes = parameters.getSupportedFocusModes();
+ if (focusModes != null) {
+ if (cameraType == 0) {
+ if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
+ parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ }
+ } else {
+ if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
+ parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
+ }
+ }
+ }
+ }
+ parameters.setRotation(90);//设置旋转代码,
+ switch (cameraFlash) {
+ case 0:
+ parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
+ break;
+ case 1:
+ parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
+ break;
+ case 2:
+ parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
+ break;
+ }
+ List pictureSizes = parameters.getSupportedPictureSizes();
+ List previewSizes = parameters.getSupportedPreviewSizes();
+ if (!isEmpty(pictureSizes) && !isEmpty(previewSizes)) {
+ /*for (Camera.Size size : pictureSizes) {
+ LogUtils.i("pictureSize " + size.width + " " + size.height);
+ }
+ for (Camera.Size size : pictureSizes) {
+ LogUtils.i("previewSize " + size.width + " " + size.height);
+ }*/
+ Camera.Size optimalPicSize = getOptimalSize(pictureSizes, width, height);
+ Camera.Size optimalPreSize = getOptimalSize(previewSizes, width, height);
+ LogUtils.i("TextureSize " + width + " " + height + " optimalSize pic " + optimalPicSize.width + " " + optimalPicSize.height + " pre " + optimalPreSize.width + " " + optimalPreSize.height);
+ parameters.setPictureSize(optimalPicSize.width, optimalPicSize.height);
+ parameters.setPreviewSize(optimalPreSize.width, optimalPreSize.height);
+ mProfile.videoFrameWidth = optimalPreSize.width;
+ mProfile.videoFrameHeight = optimalPreSize.height;
+ mProfile.videoBitRate = 5000000;//此参数主要决定视频拍出大小
+ }
+ mCamera.setParameters(parameters);
+ }
+
+ /**
+ * 释放摄像头
+ */
+ public void closeCamera() {
+ this.cameraType = 0;
+ if (mCamera != null) {
+ try {
+ mCamera.stopPreview();
+ mCamera.release();
+ mCamera = null;
+ } catch (Exception e) {
+ LogUtils.i(e);
+ if (mCamera != null) {
+ mCamera.release();
+ mCamera = null;
+ }
+ }
+ }
+ }
+
+ /**
+ * 集合不为空
+ *
+ * @param list
+ * @param
+ * @return
+ */
+ private boolean isEmpty(List list) {
+ return list == null || list.isEmpty();
+ }
+
+ /**
+ * 获取最佳预览相机Size参数
+ *
+ * @return
+ */
+ private Camera.Size getOptimalSize(List sizes, int w, int h) {
+ Camera.Size optimalSize = null;
+ float targetRadio = h / (float) w;
+ float optimalDif = Float.MAX_VALUE; //最匹配的比例
+ int optimalMaxDif = Integer.MAX_VALUE;//最优的最大值差距
+ for (Camera.Size size : sizes) {
+ float newOptimal = size.width / (float) size.height;
+ float newDiff = Math.abs(newOptimal - targetRadio);
+ if (newDiff < optimalDif) { //更好的尺寸
+ optimalDif = newDiff;
+ optimalSize = size;
+ optimalMaxDif = Math.abs(h - size.width);
+ } else if (newDiff == optimalDif) {//更好的尺寸
+ int newOptimalMaxDif = Math.abs(h - size.width);
+ if (newOptimalMaxDif < optimalMaxDif) {
+ optimalDif = newDiff;
+ optimalSize = size;
+ optimalMaxDif = newOptimalMaxDif;
+ }
+ }
+ }
+ return optimalSize;
+ }
+
+ /**
+ * 缩放
+ *
+ * @param isZoomIn
+ */
+ public void handleZoom(boolean isZoomIn) {
+ if (mCamera == null) return;
+ Camera.Parameters params = mCamera.getParameters();
+ if (params == null) return;
+ if (params.isZoomSupported()) {
+ int maxZoom = params.getMaxZoom();
+ int zoom = params.getZoom();
+ if (isZoomIn && zoom < maxZoom) {
+ zoom++;
+ } else if (zoom > 0) {
+ zoom--;
+ }
+ params.setZoom(zoom);
+ mCamera.setParameters(params);
+ } else {
+ LogUtils.i("zoom not supported");
+ }
+ }
+
+ /**
+ * 更换前后置摄像
+ */
+ public void changeCameraFacing(Context context, SurfaceTexture surfaceTexture, int width, int height) {
+ if (isSupportFrontCamera) {
+ Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
+ int cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数
+ for (int i = 0; i < cameraCount; i++) {
+ Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
+ if (cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) { //现在是后置,变更为前置
+ if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位为前置
+ closeCamera();
+ cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;
+ CameraUtils.setCameraFacing(context, cameraFacing);
+ openCamera(context, surfaceTexture, width, height);
+ break;
+ }
+ } else {//现在是前置, 变更为后置
+ if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位
+ closeCamera();
+ cameraFacing = Camera.CameraInfo.CAMERA_FACING_FRONT;
+ CameraUtils.setCameraFacing(context, cameraFacing);
+ openCamera(context, surfaceTexture, width, height);
+ break;
+ }
+ }
+ }
+ } else { //不支持摄像机
+ Toast.makeText(context, "您的手机不支持前置摄像", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ /**
+ * 改变闪光状态
+ */
+ public void changeCameraFlash(SurfaceTexture surfaceTexture, int width, int height) {
+ if (!isSupportFlashCamera) {
+ Toast.makeText(context, "您的手机不支闪光", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ if (mCamera != null) {
+ Camera.Parameters parameters = mCamera.getParameters();
+ if (parameters != null) {
+ int newState = cameraFlash;
+ switch (cameraFlash) {
+ case 0: //自动
+ parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
+ newState = 1;
+ break;
+ case 1://open
+ parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
+ newState = 2;
+ break;
+ case 2: //close
+ parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
+ newState = 0;
+ break;
+ }
+ cameraFlash = newState;
+ CameraUtils.setCameraFlash(context, newState);
+ mCamera.setParameters(parameters);
+ }
+ }
+ }
+
+ /**
+ * 拍照
+ */
+ public void takePhoto(Camera.PictureCallback callback) {
+ if (mCamera != null) {
+ try {
+ mCamera.takePicture(null, null, callback);
+ } catch (Exception e) {
+ Toast.makeText(context, "拍摄失败", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+
+
+ /**
+ * 开始录制视频
+ */
+ public void startMediaRecord(String savePath) {
+ if (mCamera == null || mProfile == null) return;
+ mCamera.unlock();
+ if (mMediaRecorder == null) {
+ mMediaRecorder = new MediaRecorder();
+ mMediaRecorder.setOrientationHint(90);
+ }
+ if (isCameraFrontFacing()) {
+ mMediaRecorder.setOrientationHint(270);
+ }
+ mMediaRecorder.reset();
+ mMediaRecorder.setCamera(mCamera);
+ mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+ mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
+ mMediaRecorder.setProfile(mProfile);
+ mMediaRecorder.setOutputFile(savePath);
+ try {
+ mMediaRecorder.prepare();
+ mMediaRecorder.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ }
+
+ /**
+ * 停止录制
+ */
+ public void stopMediaRecord() {
+ this.cameraType = 0;
+ stopRecorder();
+ releaseMediaRecorder();
+ }
+
+ private void releaseMediaRecorder() {
+ if (mMediaRecorder != null) {
+ try {
+ mMediaRecorder.reset();
+ mMediaRecorder.release();
+ mMediaRecorder = null;
+ mCamera.lock();
+ } catch (Exception e) {
+ e.printStackTrace();
+ LogUtils.i(e);
+ }
+ }
+ }
+
+ private void stopRecorder() {
+ if (mMediaRecorder != null) {
+ try {
+ mMediaRecorder.stop();
+ } catch (Exception e) {
+ e.printStackTrace();
+ LogUtils.i(e);
+ }
+
+ }
+ }
+
+ public boolean isSupportFrontCamera() {
+ return isSupportFrontCamera;
+ }
+
+ public boolean isSupportFlashCamera() {
+ return isSupportFlashCamera;
+ }
+
+ public boolean isCameraFrontFacing() {
+ return cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT;
+ }
+
+ /**
+ * 设置对焦类型
+ *
+ * @param cameraType
+ */
+ public void setCameraType(int cameraType) {
+ this.cameraType = cameraType;
+ if (mCamera != null) {//拍摄视频时
+ if (cameraFacing == Camera.CameraInfo.CAMERA_FACING_BACK) {
+ Camera.Parameters parameters = mCamera.getParameters();
+ List focusModes = parameters.getSupportedFocusModes();
+ if (focusModes != null) {
+ if (cameraType == 0) {
+ if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
+ parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
+ }
+ } else {
+ if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
+ parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public int getCameraFlash() {
+ return cameraFlash;
+ }
+
+ /**
+ * 对焦
+ *
+ * @param x
+ * @param y
+ */
+ public void handleFocusMetering(float x, float y) {
+ if (mCamera == null) { // TODO:2019/05/22 使用三星手机发送小视频时会报空指针异常,这里先判断非空,后续查找原因
+ return;
+ }
+ Camera.Parameters params = mCamera.getParameters();
+ Camera.Size previewSize = params.getPreviewSize();
+ Rect focusRect = calculateTapArea(x, y, 1f, previewSize);
+ Rect meteringRect = calculateTapArea(x, y, 1.5f, previewSize);
+ mCamera.cancelAutoFocus();
+
+ if (params.getMaxNumFocusAreas() > 0) {
+ List focusAreas = new ArrayList<>();
+ focusAreas.add(new Camera.Area(focusRect, 1000));
+ params.setFocusAreas(focusAreas);
+ } else {
+ LogUtils.i("focus areas not supported");
+ }
+ if (params.getMaxNumMeteringAreas() > 0) {
+ List meteringAreas = new ArrayList<>();
+ meteringAreas.add(new Camera.Area(meteringRect, 1000));
+ params.setMeteringAreas(meteringAreas);
+ } else {
+ LogUtils.i("metering areas not supported");
+ }
+ final String currentFocusMode = params.getFocusMode();
+ params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
+ mCamera.setParameters(params);
+
+ mCamera.autoFocus(new Camera.AutoFocusCallback() {
+ @Override
+ public void onAutoFocus(boolean success, Camera camera) {
+ Camera.Parameters params = camera.getParameters();
+ params.setFocusMode(currentFocusMode);
+ camera.setParameters(params);
+ }
+ });
+ }
+
+ private Rect calculateTapArea(float x, float y, float coefficient, Camera.Size previewSize) {
+ float focusAreaSize = 300;
+ int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();
+ int centerX = (int) (x / previewSize.width - 1000);
+ int centerY = (int) (y / previewSize.height - 1000);
+ int left = clamp(centerX - areaSize / 2, -1000, 1000);
+ int top = clamp(centerY - areaSize / 2, -1000, 1000);
+ RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
+ return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom));
+ }
+
+ private int clamp(int x, int min, int max) {
+ if (x > max) {
+ return max;
+ }
+ if (x < min) {
+ return min;
+ }
+ return x;
+ }
+
+}
diff --git a/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/utils/FileUtils.java b/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/utils/FileUtils.java
index cece39af..62db9ca7 100755
--- a/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/utils/FileUtils.java
+++ b/chatapp/src/main/java/jiguang/chat/utils/photovideo/takevideo/utils/FileUtils.java
@@ -8,6 +8,7 @@
import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;
+import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
@@ -22,6 +23,7 @@
public class FileUtils {
+ private static final String TAG = FileUtils.class.getSimpleName();
/**
* 随机命名
*/
@@ -143,13 +145,17 @@ public static String getUploadVideoFile(Context context) {
*/
public static boolean savePhoto(String photoPath, byte[] data, boolean isFrontFacing) {
if (photoPath != null && data != null) {
+ int degree = getOrientation(data);
FileOutputStream fos = null;
try {
Bitmap preBitmap = compressBitmap(data, MAX_WIDTH, MAX_HEIGHT);
+ Matrix matrix = new Matrix();
+ matrix.postRotate(degree);
if (isFrontFacing) {
- Matrix matrix = new Matrix();
matrix.postScale(1, -1);
- Bitmap newBitmap = Bitmap.createBitmap(preBitmap, 0, 0, preBitmap.getWidth(), preBitmap.getHeight(), matrix, true);
+ }
+ Bitmap newBitmap = Bitmap.createBitmap(preBitmap, 0, 0, preBitmap.getWidth(), preBitmap.getHeight(), matrix, true);
+ if (preBitmap != newBitmap) {
preBitmap.recycle();
preBitmap = newBitmap;
}
@@ -360,4 +366,117 @@ public static boolean writeFile(String str, File file, boolean append) {
return false;
}
+ public static int getOrientation(byte[] jpeg) {
+ if (jpeg == null) {
+ return 0;
+ }
+
+ int offset = 0;
+ int length = 0;
+
+ // ISO/IEC 10918-1:1993(E)
+ while (offset + 3 < jpeg.length && (jpeg[offset++] & 0xFF) == 0xFF) {
+ int marker = jpeg[offset] & 0xFF;
+
+ // Check if the marker is a padding.
+ if (marker == 0xFF) {
+ continue;
+ }
+ offset++;
+
+ // Check if the marker is SOI or TEM.
+ if (marker == 0xD8 || marker == 0x01) {
+ continue;
+ }
+ // Check if the marker is EOI or SOS.
+ if (marker == 0xD9 || marker == 0xDA) {
+ break;
+ }
+
+ // Get the length and check if it is reasonable.
+ length = pack(jpeg, offset, 2, false);
+ if (length < 2 || offset + length > jpeg.length) {
+ Log.e("69523", "Invalid length");
+ return 0;
+ }
+
+ // Break if the marker is EXIF in APP1.
+ if (marker == 0xE1 && length >= 8 &&
+ pack(jpeg, offset + 2, 4, false) == 0x45786966 &&
+ pack(jpeg, offset + 6, 2, false) == 0) {
+ offset += 8;
+ length -= 8;
+ break;
+ }
+
+ // Skip other markers.
+ offset += length;
+ length = 0;
+ }
+
+ // JEITA CP-3451 Exif Version 2.2
+ if (length > 8) {
+ // Identify the byte order.
+ int tag = pack(jpeg, offset, 4, false);
+ if (tag != 0x49492A00 && tag != 0x4D4D002A) {
+ Log.e("69523", "Invalid byte order");
+ return 0;
+ }
+ boolean littleEndian = (tag == 0x49492A00);
+
+ // Get the offset and check if it is reasonable.
+ int count = pack(jpeg, offset + 4, 4, littleEndian) + 2;
+ if (count < 10 || count > length) {
+ Log.e(TAG, "Invalid offset");
+ return 0;
+ }
+ offset += count;
+ length -= count;
+
+ // Get the count and go through all the elements.
+ count = pack(jpeg, offset - 2, 2, littleEndian);
+ while (count-- > 0 && length >= 12) {
+ // Get the tag and check if it is orientation.
+ tag = pack(jpeg, offset, 2, littleEndian);
+ if (tag == 0x0112) {
+ // We do not really care about type and count, do we?
+ int orientation = pack(jpeg, offset + 8, 2, littleEndian);
+ switch (orientation) {
+ case 1:
+ return 0;
+ case 3:
+ return 180;
+ case 6:
+ return 90;
+ case 8:
+ return 270;
+ }
+ Log.i(TAG, "Unsupported orientation");
+ return 0;
+ }
+ offset += 12;
+ length -= 12;
+ }
+ }
+
+ Log.i(TAG, "Orientation not found");
+ return 0;
+ }
+
+ private static int pack(byte[] bytes, int offset, int length,
+ boolean littleEndian) {
+ int step = 1;
+ if (littleEndian) {
+ offset += length - 1;
+ step = -1;
+ }
+
+ int value = 0;
+ while (length-- > 0) {
+ value = (value << 8) | (bytes[offset] & 0xFF);
+ offset += step;
+ }
+ return value;
+ }
+
}
diff --git a/chatapp/src/main/java/jiguang/chat/view/ChatDetailView.java b/chatapp/src/main/java/jiguang/chat/view/ChatDetailView.java
index 26beed58..811995ce 100644
--- a/chatapp/src/main/java/jiguang/chat/view/ChatDetailView.java
+++ b/chatapp/src/main/java/jiguang/chat/view/ChatDetailView.java
@@ -25,8 +25,6 @@ public class ChatDetailView extends LinearLayout {
private LinearLayout mGroupDescLL;
- private View mSplitLine1;
- private View mSplitLine2;
private LinearLayout mGroupNameLL;
private LinearLayout mMyNameLL;
private LinearLayout mGroupNumLL;
@@ -52,6 +50,11 @@ public class ChatDetailView extends LinearLayout {
private LinearLayout mDetailAddFriend;
private RelativeLayout mClear_rl;
private ImageView mIv_groupAvatar;
+ private TextView mMoreGroupMember;
+ private TextView mTv_memberCount;
+ private TextView mTv_groupType;
+ private TextView mTv_groupID;
+ private LinearLayout mChat_silence;
public ChatDetailView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -62,8 +65,6 @@ public ChatDetailView(Context context, AttributeSet attrs) {
public void initModule() {
mGroupDescLL = (LinearLayout) findViewById(R.id.group_desc_ll);
mGroupDesc = (TextView) findViewById(R.id.chat_detail_group_desc);
- mSplitLine1 = findViewById(R.id.all_member_split_line1);
- mSplitLine2 = findViewById(R.id.all_member_split_line2);
mGroupNameLL = (LinearLayout) findViewById(R.id.group_name_ll);
mGroupAvatarLL = (RelativeLayout) findViewById(R.id.rl_groupAvatar);
mIv_groupAvatar = (ImageView) findViewById(R.id.iv_groupAvatar);
@@ -72,6 +73,7 @@ public void initModule() {
mGroupChatRecordLL = (LinearLayout) findViewById(R.id.group_chat_record_ll);
mGroupChatDelLL = (LinearLayout) findViewById(R.id.group_chat_del_ll);
mChatFile = (LinearLayout) findViewById(R.id.chat_file);
+ mChat_silence = findViewById(R.id.chat_silence);
mReturnBtn = (ImageButton) findViewById(R.id.return_btn);
mTitle = (TextView) findViewById(R.id.title);
mMenuBtn = (ImageButton) findViewById(R.id.right_btn);
@@ -84,6 +86,10 @@ public void initModule() {
mBlockBtn = (SlipButton) findViewById(R.id.block_slip_btn);
mBlockLine = findViewById(R.id.block_split_line);
mTv_moreGroup = (LinearLayout) findViewById(R.id.tv_moreGroup);
+ mTv_memberCount = findViewById(R.id.tv_memberCount);
+ mMoreGroupMember = findViewById(R.id.moreGroupMember);
+ mTv_groupType = findViewById(R.id.tv_groupType);
+ mTv_groupID = findViewById(R.id.tv_groupID);
mAddFriend = (Button) findViewById(R.id.chat_detail_add_friend);
mDetailAddFriend = (LinearLayout) findViewById(R.id.detail_add_friend);
mClear_rl = (RelativeLayout) findViewById(R.id.clear_rl);
@@ -106,9 +112,12 @@ public void setListeners(OnClickListener onClickListener) {
mReturnBtn.setOnClickListener(onClickListener);
mDelGroupBtn.setOnClickListener(onClickListener);
mTv_moreGroup.setOnClickListener(onClickListener);
+ mMoreGroupMember.setOnClickListener(onClickListener);
mAddFriend.setOnClickListener(onClickListener);
mClear_rl.setOnClickListener(onClickListener);
mChatFile.setOnClickListener(onClickListener);
+ mChat_silence.setOnClickListener(onClickListener);
+
}
public void setOnChangeListener(SlipButton.OnChangedListener listener) {
@@ -120,6 +129,18 @@ public void setItemListener(AdapterView.OnItemClickListener listener) {
mGridView.setOnItemClickListener(listener);
}
+ public void setGroupType(String type) {
+ mTv_groupType.setText(type);
+ }
+
+ public void setGroupId(String groupId) {
+ mTv_groupID.setText(groupId);
+ }
+
+ public void setMemberCount(String count) {
+ mTv_memberCount.setText(count);
+ }
+
public void setTitle(String title) {
mTitle.setText(title);
}
@@ -144,10 +165,19 @@ public void setSingleView(boolean friend) {
mDetailAddFriend.setVisibility(VISIBLE);
mDelGroupBtn.setVisibility(GONE);
}
+ mGroupDescLL.setVisibility(View.GONE);
mGroupNameLL.setVisibility(View.GONE);
mGroupAvatarLL.setVisibility(View.GONE);
mGroupNumLL.setVisibility(View.GONE);
mMyNameLL.setVisibility(View.GONE);
+ findViewById(R.id.group_id).setVisibility(View.GONE);
+ findViewById(R.id.group_type).setVisibility(View.GONE);
+ findViewById(R.id.chat_silence).setVisibility(View.GONE);
+ findViewById(R.id.single_chat_remove_1).setVisibility(View.GONE);
+ findViewById(R.id.single_chat_remove_2).setVisibility(View.GONE);
+ findViewById(R.id.single_chat_remove_3).setVisibility(View.GONE);
+ findViewById(R.id.single_chat_remove_4).setVisibility(View.GONE);
+ findViewById(R.id.single_chat_remove_5).setVisibility(View.GONE);
mDelGroupBtn.setText("删除好友");
}
@@ -164,12 +194,6 @@ public void setGroupDesc(String desc) {
mGroupDesc.setText(desc);
}
- public void dismissAllMembersBtn() {
- mSplitLine1.setVisibility(View.GONE);
- mSplitLine2.setVisibility(View.GONE);
- mGroupDescLL.setVisibility(View.GONE);
- }
-
public void initNoDisturb(int status) {
mNoDisturbBtn.setChecked(status == 1);
}
diff --git a/chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java b/chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java
new file mode 100644
index 00000000..9d96e117
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/view/ChatRoomView.java
@@ -0,0 +1,79 @@
+package jiguang.chat.view;
+
+import android.content.Context;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.scwang.smartrefresh.layout.SmartRefreshLayout;
+import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener;
+import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
+
+import jiguang.chat.R;
+import jiguang.chat.adapter.ChatRoomAdapter;
+import jiguang.chat.controller.ChatRoomController;
+
+/**
+ * Created by ${chenyn} on 2017/10/31.
+ */
+
+public class ChatRoomView extends LinearLayout {
+ private ChatRoomController mListener;
+ private Context mContext;
+ private ListView mChatRoomListView;
+ private LayoutInflater mInflater;
+ private LinearLayout mSearch_title;
+ private SmartRefreshLayout smartRefreshLayout;
+ private TextView mNullChatRoom;
+
+ public ChatRoomView(Context context) {
+ super(context);
+ }
+
+ public ChatRoomView(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ this.mContext = context;
+ mInflater = LayoutInflater.from(context);
+ }
+
+
+ public void initModule() {
+ View view = LayoutInflater.from(mContext).inflate(R.layout.item_search, null);
+ TextView titleText = view.findViewById(R.id.tv_chatRoomTitle);
+ titleText.setText("聊天室ID");
+ mSearch_title = view.findViewById(R.id.search_title);
+ mChatRoomListView = findViewById(R.id.lv_chatRoom);
+ mChatRoomListView.addHeaderView(view);
+ smartRefreshLayout = findViewById(R.id.refreshLayout);
+ mNullChatRoom = findViewById(R.id.null_chatRoom);
+ }
+
+ public void setListener(ChatRoomController listener) {
+ mChatRoomListView.setOnItemClickListener(listener);
+ }
+
+ public void setClickListener(ChatRoomController listener) {
+ mSearch_title.setOnClickListener(listener);
+ }
+
+ public void setChatRoomAdapter(ChatRoomAdapter chatRoomAdapter) {
+ mChatRoomListView.setAdapter(chatRoomAdapter);
+ }
+
+ public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
+ smartRefreshLayout.setOnRefreshListener(onRefreshListener);
+ }
+
+ public void setOnLoadMoreListener(OnLoadMoreListener loadMoreListener) {
+ smartRefreshLayout.setOnLoadMoreListener(loadMoreListener);
+ }
+
+ public void setNullChatRoom(boolean isNullChatRoom) {
+ mNullChatRoom.setVisibility(isNullChatRoom ? VISIBLE : GONE);
+ }
+
+}
diff --git a/chatapp/src/main/java/jiguang/chat/view/ChatView.java b/chatapp/src/main/java/jiguang/chat/view/ChatView.java
index 52151178..160b111d 100644
--- a/chatapp/src/main/java/jiguang/chat/view/ChatView.java
+++ b/chatapp/src/main/java/jiguang/chat/view/ChatView.java
@@ -50,16 +50,20 @@ public void initModule(float density, int densityDpi) {
mChatTitle = (TextView) findViewById(R.id.jmui_title);
mAtMeBtn = (Button) findViewById(R.id.jmui_at_me_btn);
if (densityDpi <= 160) {
- mChatTitle.setMaxWidth((int)(180 * density + 0.5f));
- }else if (densityDpi <= 240) {
- mChatTitle.setMaxWidth((int)(190 * density + 0.5f));
- }else {
- mChatTitle.setMaxWidth((int)(200 * density + 0.5f));
+ mChatTitle.setMaxWidth((int) (180 * density + 0.5f));
+ } else if (densityDpi <= 240) {
+ mChatTitle.setMaxWidth((int) (190 * density + 0.5f));
+ } else {
+ mChatTitle.setMaxWidth((int) (200 * density + 0.5f));
}
mChatListView = (DropDownListView) findViewById(R.id.lv_chat);
}
+ public DropDownListView getChatListView() {
+ return mChatListView;
+ }
+
public void setToPosition(int position) {
mChatListView.smoothScrollToPosition(position);
mAtMeBtn.setVisibility(GONE);
@@ -72,6 +76,7 @@ public void setChatListAdapter(ChattingListAdapter chatAdapter) {
public DropDownListView getListView() {
return mChatListView;
}
+
public void setToBottom() {
mChatListView.clearFocus();
mChatListView.post(new Runnable() {
@@ -81,6 +86,7 @@ public void run() {
}
});
}
+
public void setConversation(Conversation conv) {
this.mConv = conv;
}
@@ -112,6 +118,7 @@ public void setChatTitle(int id, int count) {
public void setChatTitle(int id) {
mChatTitle.setText(id);
}
+
public void showAtMeButton() {
mAtMeBtn.setVisibility(VISIBLE);
}
@@ -127,6 +134,11 @@ public void setChatTitle(String name, int count) {
public void setChatTitle(String title) {
mChatTitle.setText(title);
}
+
+ public void setTitle(String title) {
+ mChatTitle.setText(title);
+ }
+
public void dismissGroupNum() {
mGroupNumTv.setVisibility(View.GONE);
}
diff --git a/chatapp/src/main/java/jiguang/chat/view/ContactsView.java b/chatapp/src/main/java/jiguang/chat/view/ContactsView.java
index a4b9d22c..1679a7fe 100644
--- a/chatapp/src/main/java/jiguang/chat/view/ContactsView.java
+++ b/chatapp/src/main/java/jiguang/chat/view/ContactsView.java
@@ -18,7 +18,7 @@
import jiguang.chat.controller.ContactsController;
import jiguang.chat.utils.SharePreferenceManager;
import jiguang.chat.utils.sidebar.SideBar;
-import jiguang.chat.view.listview.StickyListHeadersListView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
/**
@@ -75,13 +75,16 @@ public void initModule(float ratio, float density) {
RelativeLayout loadingHeader = (RelativeLayout) mInflater.inflate(R.layout.jmui_drop_down_list_header, null);
mLoadingIv = (ImageView) loadingHeader.findViewById(R.id.jmui_loading_img);
mLoadingTv = (LinearLayout) loadingHeader.findViewById(R.id.loading_view);
- mNewFriendNum.setVisibility(INVISIBLE);
mListView.addHeaderView(loadingHeader);
mListView.addHeaderView(header, null, false);
mListView.setDrawingListUnderStickyHeader(true);
mListView.setAreHeadersSticky(true);
mListView.setStickyHeaderTopOffset(0);
-
+ if (SharePreferenceManager.getCachedNewFriendNum() > 0) {
+ showNewFriends(SharePreferenceManager.getCachedNewFriendNum());
+ } else {
+ mNewFriendNum.setVisibility(INVISIBLE);
+ }
}
@@ -115,6 +118,7 @@ public void showNewFriends(int num) {
public void dismissNewFriends() {
SharePreferenceManager.setCachedNewFriendNum(0);
+ JGApplication.forAddIntoGroup.clear();
JGApplication.forAddFriend.clear();
mNewFriendNum.setVisibility(INVISIBLE);
}
diff --git a/chatapp/src/main/java/jiguang/chat/view/MainView.java b/chatapp/src/main/java/jiguang/chat/view/MainView.java
index 94e52ab3..97ac9bb1 100644
--- a/chatapp/src/main/java/jiguang/chat/view/MainView.java
+++ b/chatapp/src/main/java/jiguang/chat/view/MainView.java
@@ -6,8 +6,10 @@
import android.util.AttributeSet;
import android.widget.Button;
import android.widget.RelativeLayout;
+import android.widget.TextView;
import jiguang.chat.R;
+import jiguang.chat.utils.SharePreferenceManager;
/**
* Created by ${chenyn} on 2017/2/20.
@@ -18,23 +20,31 @@ public class MainView extends RelativeLayout {
private Button[] mBtnList;
private int[] mBtnListID;
private ScrollControlViewPager mViewContainer;
+ private TextView mAllContactNumber;
public MainView(Context context, AttributeSet attrs) {
super(context, attrs);
}
-
public void initModule() {
mBtnListID = new int[] {
- R.id.actionbar_msg_btn, R.id.actionbar_contact_btn, R.id.actionbar_me_btn
- };
- mBtnList = new Button[3];
- for (int i = 0; i < 3; i++) {
+ R.id.actionbar_msg_btn, R.id.actionbar_chatroom_btn,
+ R.id.actionbar_contact_btn, R.id.actionbar_me_btn};
+ mBtnList = new Button[mBtnListID.length];
+ for (int i = 0; i < mBtnListID.length; i++) {
mBtnList[i] = (Button) findViewById(mBtnListID[i]);
}
mViewContainer = (ScrollControlViewPager) findViewById(R.id.viewpager);
+ mViewContainer.setOffscreenPageLimit(2);
mBtnList[0].setTextColor(getResources().getColor(R.color.actionbar_pres_color));
mBtnList[0].setSelected(true);
+ mAllContactNumber = findViewById(R.id.all_contact_number);
+ if (SharePreferenceManager.getCachedNewFriendNum() > 0) {
+ mAllContactNumber.setVisibility(VISIBLE);
+ mAllContactNumber.setText(String.valueOf(SharePreferenceManager.getCachedNewFriendNum()));
+ } else {
+ mAllContactNumber.setVisibility(GONE);
+ }
}
public void setOnClickListener(OnClickListener onclickListener) {
@@ -56,7 +66,7 @@ public void setCurrentItem(int index, boolean scroll) {
}
public void setButtonColor(int index) {
- for (int i = 0; i < 3; i++) {
+ for (int i = 0; i < mBtnListID.length; i++) {
if (index == i) {
mBtnList[i].setSelected(true);
mBtnList[i].setTextColor(getResources().getColor(R.color.actionbar_pres_color));
diff --git a/chatapp/src/main/java/jiguang/chat/view/MenuItemView.java b/chatapp/src/main/java/jiguang/chat/view/MenuItemView.java
index 0407bfce..912811f9 100644
--- a/chatapp/src/main/java/jiguang/chat/view/MenuItemView.java
+++ b/chatapp/src/main/java/jiguang/chat/view/MenuItemView.java
@@ -1,7 +1,7 @@
package jiguang.chat.view;
import android.view.View;
-import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
import jiguang.chat.R;
@@ -9,20 +9,22 @@
public class MenuItemView {
private View mView;
- private LinearLayout mCreateGroupLl;
- private LinearLayout mAddFriendLl;
- private LinearLayout mSendMsgLl;
- private LinearLayout mLl_saoYiSao;
+ private RelativeLayout mCreateGroupLl;
+ private RelativeLayout mAddFriendLl;
+ private RelativeLayout mSendMsgLl;
+ private RelativeLayout mLl_saoYiSao;
+ private RelativeLayout mAdd_open_group;
public MenuItemView(View view) {
this.mView = view;
}
public void initModule() {
- mCreateGroupLl = (LinearLayout) mView.findViewById(R.id.create_group_ll);
- mAddFriendLl = (LinearLayout) mView.findViewById(R.id.add_friend_with_confirm_ll);
- mSendMsgLl = (LinearLayout) mView.findViewById(R.id.send_message_ll);
- mLl_saoYiSao = (LinearLayout) mView.findViewById(R.id.ll_saoYiSao);
+ mCreateGroupLl = mView.findViewById(R.id.create_group_ll);
+ mAddFriendLl = mView.findViewById(R.id.add_friend_with_confirm_ll);
+ mSendMsgLl = mView.findViewById(R.id.send_message_ll);
+ mLl_saoYiSao = mView.findViewById(R.id.ll_saoYiSao);
+ mAdd_open_group = mView.findViewById(R.id.add_open_group);
}
public void setListeners(View.OnClickListener listener) {
@@ -30,6 +32,7 @@ public void setListeners(View.OnClickListener listener) {
mAddFriendLl.setOnClickListener(listener);
mSendMsgLl.setOnClickListener(listener);
mLl_saoYiSao.setOnClickListener(listener);
+ mAdd_open_group.setOnClickListener(listener);
}
public void showAddFriendDirect() {
diff --git a/chatapp/src/main/java/jiguang/chat/view/NoScrollGridView.java b/chatapp/src/main/java/jiguang/chat/view/NoScrollGridView.java
new file mode 100644
index 00000000..745f8f8e
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/view/NoScrollGridView.java
@@ -0,0 +1,48 @@
+package jiguang.chat.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.GridView;
+
+public class NoScrollGridView extends GridView {
+ private int mRequestedNumColumns = 0;
+
+ public NoScrollGridView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public NoScrollGridView(Context context) {
+ super(context);
+ }
+
+ public NoScrollGridView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public void setNumColumns(int numColumns) {
+ super.setNumColumns(numColumns);
+ if (numColumns != mRequestedNumColumns) {
+ mRequestedNumColumns = numColumns;
+ }
+ }
+
+ /**
+ * 设置gridView不可滑动,并且设置gridView宽度
+ * @param widthMeasureSpec
+ * @param heightMeasureSpec
+ */
+ @Override
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int expandSpec = MeasureSpec.makeMeasureSpec(
+ Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+ super.onMeasure(widthMeasureSpec, expandSpec);
+ if (mRequestedNumColumns > 0) {
+ int width = (mRequestedNumColumns * getColumnWidth())
+ + ((mRequestedNumColumns-1) * getHorizontalSpacing())
+ + getListPaddingLeft() + getListPaddingRight();
+
+ setMeasuredDimension(width, getMeasuredHeight());
+ }
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/view/NoScrollViewPager.java b/chatapp/src/main/java/jiguang/chat/view/NoScrollViewPager.java
new file mode 100644
index 00000000..97b0695b
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/view/NoScrollViewPager.java
@@ -0,0 +1,35 @@
+package jiguang.chat.view;
+
+import android.content.Context;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+/**
+ * Created by ${chenyn} on 2017/10/22.
+ */
+
+public class NoScrollViewPager extends ViewPager {
+ public NoScrollViewPager(Context context) {
+ super(context);
+ }
+
+ public NoScrollViewPager(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ return super.dispatchTouchEvent(ev);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ return false;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ return true;
+ }
+}
diff --git a/chatapp/src/main/java/jiguang/chat/view/RecordVoiceButton.java b/chatapp/src/main/java/jiguang/chat/view/RecordVoiceButton.java
index 9805f4a3..23a54ee8 100644
--- a/chatapp/src/main/java/jiguang/chat/view/RecordVoiceButton.java
+++ b/chatapp/src/main/java/jiguang/chat/view/RecordVoiceButton.java
@@ -36,6 +36,7 @@
import cn.jpush.im.android.api.model.Message;
import cn.jpush.im.android.api.model.UserInfo;
import cn.jpush.im.android.api.options.MessageSendingOptions;
+import cn.jpush.im.api.BasicCallback;
import jiguang.chat.R;
import jiguang.chat.adapter.ChattingListAdapter;
import jiguang.chat.utils.FileHelper;
@@ -80,6 +81,7 @@ public class RecordVoiceButton extends Button {
private Chronometer mVoiceTime;
private TextView mTimeDown;
private LinearLayout mMicShow;
+ private String mUserName;
public RecordVoiceButton(Context context) {
super(context);
@@ -111,6 +113,10 @@ public void initConv(Conversation conv, ChattingListAdapter adapter, ChatView ch
this.mMsgListAdapter = adapter;
mChatView = chatView;
+ if (conv.getType() == ConversationType.single) {
+ UserInfo userInfo = (UserInfo) conv.getTargetInfo();
+ mUserName = userInfo.getUserName();
+ }
}
@Override
@@ -121,6 +127,14 @@ public boolean onTouchEvent(MotionEvent event) {
mTimeShort.setContentView(R.layout.send_voice_time_short);
switch (action) {
case MotionEvent.ACTION_DOWN:
+ if (mConv.getType() == ConversationType.single) {
+ JMessageClient.sendSingleTransCommand(mUserName, null, "对方正在说话...", new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+
+ }
+ });
+ }
//文字 松开结束
this.setText(mContext.getString(R.string.jmui_send_voice_hint));
mIsPressed = true;
@@ -149,6 +163,14 @@ public void run() {
}
break;
case MotionEvent.ACTION_UP:
+ if (mConv.getType() == ConversationType.single) {
+ JMessageClient.sendSingleTransCommand(mUserName, null, mConv.getTitle(), new BasicCallback() {
+ @Override
+ public void gotResult(int i, String s) {
+
+ }
+ });
+ }
//文字 按住说话
this.setText(mContext.getString(R.string.jmui_record_voice_hint));
mIsPressed = false;
@@ -515,7 +537,7 @@ public void handleMessage(android.os.Message msg) {
// .getString(controller.mContext, "jmui_rest_record_time_hint")), restTime));
controller.mMicShow.setVisibility(GONE);
controller.mTimeDown.setVisibility(VISIBLE);
- controller.mTimeDown.setText(restTime+"");
+ controller.mTimeDown.setText(restTime + "");
// 倒计时结束,发送语音, 重置状态
} else if (restTime == 0) {
diff --git a/chatapp/src/main/java/jiguang/chat/view/SelectFriendView.java b/chatapp/src/main/java/jiguang/chat/view/SelectFriendView.java
index c0f56cb2..21331812 100644
--- a/chatapp/src/main/java/jiguang/chat/view/SelectFriendView.java
+++ b/chatapp/src/main/java/jiguang/chat/view/SelectFriendView.java
@@ -11,7 +11,7 @@
import jiguang.chat.R;
import jiguang.chat.adapter.StickyListAdapter;
import jiguang.chat.utils.sidebar.SideBar;
-import jiguang.chat.view.listview.StickyListHeadersListView;
+import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
public class SelectFriendView extends LinearLayout {
diff --git a/chatapp/src/main/java/jiguang/chat/view/listview/AdapterWrapper.java b/chatapp/src/main/java/jiguang/chat/view/listview/AdapterWrapper.java
index 84f60466..092bf047 100644
--- a/chatapp/src/main/java/jiguang/chat/view/listview/AdapterWrapper.java
+++ b/chatapp/src/main/java/jiguang/chat/view/listview/AdapterWrapper.java
@@ -12,8 +12,9 @@
import java.util.LinkedList;
import java.util.List;
+
import jiguang.chat.view.CheckableWrapperView;
-import jiguang.chat.adapter.StickyListHeadersAdapter;
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
/**
diff --git a/chatapp/src/main/java/jiguang/chat/view/listview/LoadMoreListView.java b/chatapp/src/main/java/jiguang/chat/view/listview/LoadMoreListView.java
new file mode 100644
index 00000000..22781384
--- /dev/null
+++ b/chatapp/src/main/java/jiguang/chat/view/listview/LoadMoreListView.java
@@ -0,0 +1,114 @@
+package jiguang.chat.view.listview;
+
+import android.content.Context;
+import android.graphics.drawable.AnimationDrawable;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.AbsListView;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.RelativeLayout;
+
+import jiguang.chat.R;
+
+public class LoadMoreListView extends ListView implements AbsListView.OnScrollListener {
+
+ //是否加载中或已加载所有数据
+ private boolean mIsLoadingOrComplete;
+ //是否所有条目都可见
+ private boolean mIsAllVisible;
+
+ private OnLoadMoreListener mOnLoadMoreListener;
+ private RelativeLayout loadLayout;
+ private View mLoadCompleteView;
+
+ public LoadMoreListView(Context context) {
+ super(context);
+ init(context);
+ }
+
+ public LoadMoreListView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public LoadMoreListView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context);
+ }
+
+ //加载更多回调接口
+ public interface OnLoadMoreListener {
+ void loadMore();
+ }
+
+ //初始化
+ private void init(Context context) {
+ loadLayout = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.jmui_drop_down_list_header, null);
+ mLoadCompleteView = LayoutInflater.from(context).inflate(R.layout.load_complete, null);
+// mLoadCompleteView.setOnClickListener();
+ setOnScrollListener(this);
+ }
+
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ //(最后一条可见item==最后一条item)&&(停止滑动)&&(!加载数据中)&&(!所有条目都可见)
+ if (view.getLastVisiblePosition() == getAdapter().getCount() - 1 && scrollState == SCROLL_STATE_IDLE && !mIsLoadingOrComplete && !mIsAllVisible) {
+ if (null != mOnLoadMoreListener) {
+ //加载更多
+ mIsLoadingOrComplete = true;
+ mOnLoadMoreListener.loadMore();
+ }
+ }
+ if (getFooterViewsCount() == 0 && !mIsAllVisible) {
+ loadLayout.findViewById(R.id.loading_view).setVisibility(VISIBLE);
+ ImageView loading = loadLayout.findViewById(R.id.jmui_loading_img);
+ AnimationDrawable drawable = (AnimationDrawable) loading.getDrawable();
+ drawable.start();
+ addFooterView(loadLayout);
+ }
+ }
+
+ @Override
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+ mIsAllVisible = totalItemCount == visibleItemCount;
+ if (mIsAllVisible && !mIsLoadingOrComplete && totalItemCount > ((ListView) view).getFooterViewsCount() + ((ListView) view).getHeaderViewsCount()) {
+ if (null != mOnLoadMoreListener) {
+ mIsLoadingOrComplete = true;
+ mOnLoadMoreListener.loadMore();
+ }
+ }
+ }
+
+ /**
+ * 加载更多回调
+ *
+ * @param onLoadMoreListener 加载更多回调接口
+ */
+ public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
+ mOnLoadMoreListener = onLoadMoreListener;
+ }
+
+ /**
+ * 通知此次加载完成,remove footerView
+ *
+ * @param allComplete 是否已加载全部数据
+ */
+ public void setLoadCompleted(final boolean allComplete) {
+ if (allComplete && getFooterViewsCount() != 0) {
+ removeFooterView(loadLayout);
+ removeFooterView(mLoadCompleteView);
+ addFooterView(mLoadCompleteView);
+ } else {
+ mIsLoadingOrComplete = false;
+ }
+ }
+
+ public void updateData() {
+ mIsLoadingOrComplete = false;
+ removeFooterView(loadLayout);
+ removeFooterView(mLoadCompleteView);
+ }
+}
+
diff --git a/chatapp/src/main/java/jiguang/chat/view/listview/SectionIndexerAdapterWrapper.java b/chatapp/src/main/java/jiguang/chat/view/listview/SectionIndexerAdapterWrapper.java
index b50c13f9..ab9d2324 100644
--- a/chatapp/src/main/java/jiguang/chat/view/listview/SectionIndexerAdapterWrapper.java
+++ b/chatapp/src/main/java/jiguang/chat/view/listview/SectionIndexerAdapterWrapper.java
@@ -3,7 +3,7 @@
import android.content.Context;
import android.widget.SectionIndexer;
-import jiguang.chat.adapter.StickyListHeadersAdapter;
+import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
class SectionIndexerAdapterWrapper extends
diff --git a/chatapp/src/main/java/jiguang/chat/view/listview/StickyListHeadersListView.java b/chatapp/src/main/java/jiguang/chat/view/listview/StickyListHeadersListView.java
deleted file mode 100644
index 2893d272..00000000
--- a/chatapp/src/main/java/jiguang/chat/view/listview/StickyListHeadersListView.java
+++ /dev/null
@@ -1,1129 +0,0 @@
-package jiguang.chat.view.listview;
-
-import android.annotation.SuppressLint;
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.database.DataSetObserver;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.os.Parcelable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseBooleanArray;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.AbsListView.MultiChoiceModeListener;
-import android.widget.AbsListView.OnScrollListener;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.FrameLayout;
-import android.widget.ListView;
-import android.widget.SectionIndexer;
-
-import jiguang.chat.R;
-import jiguang.chat.adapter.StickyListHeadersAdapter;
-
-
-/**
- * Even though this is a FrameLayout subclass we still consider it a ListView.
- * This is because of 2 reasons:
- * 1. It acts like as ListView.
- * 2. It used to be a ListView subclass and refactoring the name would cause compatibility errors.
- *
- */
-public class StickyListHeadersListView extends FrameLayout {
-
- public interface OnHeaderClickListener {
- void onHeaderClick(StickyListHeadersListView l, View header,
- int itemPosition, long headerId, boolean currentlySticky);
- }
-
- /**
- * Notifies the listener when the sticky headers top offset has changed.
- */
- public interface OnStickyHeaderOffsetChangedListener {
- /**
- * @param l The view parent
- * @param header The currently sticky header being offset.
- * This header is not guaranteed to have it's measurements set.
- * It is however guaranteed that this view has been measured,
- * therefor you should user getMeasured* methods instead of
- * get* methods for determining the view's size.
- * @param offset The amount the sticky header is offset by towards to top of the screen.
- */
- void onStickyHeaderOffsetChanged(StickyListHeadersListView l, View header, int offset);
- }
-
- /**
- * Notifies the listener when the sticky header has been updated
- */
- public interface OnStickyHeaderChangedListener {
- /**
- * @param l The view parent
- * @param header The new sticky header view.
- * @param itemPosition The position of the item within the adapter's data set of
- * the item whose header is now sticky.
- * @param headerId The id of the new sticky header.
- */
- void onStickyHeaderChanged(StickyListHeadersListView l, View header,
- int itemPosition, long headerId);
-
- }
-
- /* --- Children --- */
- private WrapperViewList mList;
- private View mHeader;
-
- /* --- Header state --- */
- private Long mHeaderId;
- // used to not have to call getHeaderId() all the time
- private Integer mHeaderPosition;
- private Integer mHeaderOffset;
-
- /* --- Delegates --- */
- private OnScrollListener mOnScrollListenerDelegate;
- private AdapterWrapper mAdapter;
-
- /* --- Settings --- */
- private boolean mAreHeadersSticky = true;
- private boolean mClippingToPadding = true;
- private boolean mIsDrawingListUnderStickyHeader = true;
- private int mStickyHeaderTopOffset = 0;
- private int mPaddingLeft = 0;
- private int mPaddingTop = 0;
- private int mPaddingRight = 0;
- private int mPaddingBottom = 0;
-
- /* --- Touch handling --- */
- private float mDownY;
- private boolean mHeaderOwnsTouch;
- private float mTouchSlop;
-
- /* --- Other --- */
- private OnHeaderClickListener mOnHeaderClickListener;
- private OnStickyHeaderOffsetChangedListener mOnStickyHeaderOffsetChangedListener;
- private OnStickyHeaderChangedListener mOnStickyHeaderChangedListener;
- private AdapterWrapperDataSetObserver mDataSetObserver;
- private Drawable mDivider;
- private int mDividerHeight;
-
- public StickyListHeadersListView(Context context) {
- this(context, null);
- }
-
- public StickyListHeadersListView(Context context, AttributeSet attrs) {
- this(context, attrs, R.attr.stickyListHeadersListViewStyle);
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public StickyListHeadersListView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
-
- // Initialize the wrapped list
- mList = new WrapperViewList(context);
-
- // null out divider, dividers are handled by adapter so they look good with headers
- mDivider = mList.getDivider();
- mDividerHeight = mList.getDividerHeight();
- mList.setDivider(null);
- mList.setDividerHeight(0);
-
- if (attrs != null) {
- TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.StickyListHeadersListView, defStyle, 0);
-
- try {
- // -- View attributes --
- int padding = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_padding, 0);
- mPaddingLeft = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingLeft, padding);
- mPaddingTop = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingTop, padding);
- mPaddingRight = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingRight, padding);
- mPaddingBottom = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_paddingBottom, padding);
-
- setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom);
-
- // Set clip to padding on the list and reset value to default on
- // wrapper
- mClippingToPadding = a.getBoolean(R.styleable.StickyListHeadersListView_android_clipToPadding, true);
- super.setClipToPadding(true);
- mList.setClipToPadding(mClippingToPadding);
-
- // scrollbars
- final int scrollBars = a.getInt(R.styleable.StickyListHeadersListView_android_scrollbars, 0x00000200);
- mList.setVerticalScrollBarEnabled((scrollBars & 0x00000200) != 0);
- mList.setHorizontalScrollBarEnabled((scrollBars & 0x00000100) != 0);
-
- // overscroll
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
- mList.setOverScrollMode(a.getInt(R.styleable.StickyListHeadersListView_android_overScrollMode, 0));
- }
-
- // -- ListView attributes --
- mList.setFadingEdgeLength(a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_fadingEdgeLength,
- mList.getVerticalFadingEdgeLength()));
- final int fadingEdge = a.getInt(R.styleable.StickyListHeadersListView_android_requiresFadingEdge, 0);
- if (fadingEdge == 0x00001000) {
- mList.setVerticalFadingEdgeEnabled(false);
- mList.setHorizontalFadingEdgeEnabled(true);
- } else if (fadingEdge == 0x00002000) {
- mList.setVerticalFadingEdgeEnabled(true);
- mList.setHorizontalFadingEdgeEnabled(false);
- } else {
- mList.setVerticalFadingEdgeEnabled(false);
- mList.setHorizontalFadingEdgeEnabled(false);
- }
- mList.setCacheColorHint(a
- .getColor(R.styleable.StickyListHeadersListView_android_cacheColorHint, mList.getCacheColorHint()));
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- mList.setChoiceMode(a.getInt(R.styleable.StickyListHeadersListView_android_choiceMode,
- mList.getChoiceMode()));
- }
- mList.setDrawSelectorOnTop(a.getBoolean(R.styleable.StickyListHeadersListView_android_drawSelectorOnTop, false));
- mList.setFastScrollEnabled(a.getBoolean(R.styleable.StickyListHeadersListView_android_fastScrollEnabled,
- mList.isFastScrollEnabled()));
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- mList.setFastScrollAlwaysVisible(a.getBoolean(
- R.styleable.StickyListHeadersListView_android_fastScrollAlwaysVisible,
- mList.isFastScrollAlwaysVisible()));
- }
-
-// mList.setScrollBarStyle(a.getInt(R.styleable.StickyListHeadersListView_android_scrollbarStyle, 0));
-
- if (a.hasValue(R.styleable.StickyListHeadersListView_android_listSelector)) {
- mList.setSelector(a.getDrawable(R.styleable.StickyListHeadersListView_android_listSelector));
- }
-
- mList.setScrollingCacheEnabled(a.getBoolean(R.styleable.StickyListHeadersListView_android_scrollingCache,
- mList.isScrollingCacheEnabled()));
-
- if (a.hasValue(R.styleable.StickyListHeadersListView_android_divider)) {
- mDivider = a.getDrawable(R.styleable.StickyListHeadersListView_android_divider);
- }
-
- mList.setStackFromBottom(a.getBoolean(R.styleable.StickyListHeadersListView_android_stackFromBottom, false));
-
- mDividerHeight = a.getDimensionPixelSize(R.styleable.StickyListHeadersListView_android_dividerHeight,
- mDividerHeight);
-
- mList.setTranscriptMode(a.getInt(R.styleable.StickyListHeadersListView_android_transcriptMode,
- ListView.TRANSCRIPT_MODE_DISABLED));
-
- // -- StickyListHeaders attributes --
- mAreHeadersSticky = a.getBoolean(R.styleable.StickyListHeadersListView_hasStickyHeaders, true);
- mIsDrawingListUnderStickyHeader = a.getBoolean(
- R.styleable.StickyListHeadersListView_isDrawingListUnderStickyHeader,
- true);
- } finally {
- a.recycle();
- }
- }
-
- // attach some listeners to the wrapped list
- mList.setLifeCycleListener(new WrapperViewListLifeCycleListener());
- mList.setOnScrollListener(new WrapperListScrollListener());
-
- addView(mList);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- measureHeader(mHeader);
- }
-
- private void ensureHeaderHasCorrectLayoutParams(View header) {
- ViewGroup.LayoutParams lp = header.getLayoutParams();
- if (lp == null) {
- lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
- header.setLayoutParams(lp);
- } else if (lp.height == LayoutParams.MATCH_PARENT || lp.width == LayoutParams.WRAP_CONTENT) {
- lp.height = LayoutParams.WRAP_CONTENT;
- lp.width = LayoutParams.MATCH_PARENT;
- header.setLayoutParams(lp);
- }
- }
-
- private void measureHeader(View header) {
- if (header != null) {
- final int width = getMeasuredWidth() - mPaddingLeft - mPaddingRight;
- final int parentWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
- width, MeasureSpec.EXACTLY);
- final int parentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0,
- MeasureSpec.UNSPECIFIED);
- measureChild(header, parentWidthMeasureSpec,
- parentHeightMeasureSpec);
- }
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- mList.layout(0, 0, mList.getMeasuredWidth(), getHeight());
- if (mHeader != null) {
- MarginLayoutParams lp = (MarginLayoutParams) mHeader.getLayoutParams();
- int headerTop = lp.topMargin;
- mHeader.layout(mPaddingLeft, headerTop, mHeader.getMeasuredWidth()
- + mPaddingLeft, headerTop + mHeader.getMeasuredHeight());
- }
- }
-
- @Override
- protected void dispatchDraw(Canvas canvas) {
- // Only draw the list here.
- // The header should be drawn right after the lists children are drawn.
- // This is done so that the header is above the list items
- // but below the list decorators (scroll bars etc).
- if (mList.getVisibility() == VISIBLE || mList.getAnimation() != null) {
- drawChild(canvas, mList, 0);
- }
- }
-
- // Reset values tied the header. also remove header form layout
- // This is called in response to the data set or the adapter changing
- private void clearHeader() {
- if (mHeader != null) {
- removeView(mHeader);
- mHeader = null;
- mHeaderId = null;
- mHeaderPosition = null;
- mHeaderOffset = null;
-
- // reset the top clipping length
- mList.setTopClippingLength(0);
- updateHeaderVisibilities();
- }
- }
-
- private void updateOrClearHeader(int firstVisiblePosition) {
- final int adapterCount = mAdapter == null ? 0 : mAdapter.getCount();
- if (adapterCount == 0 || !mAreHeadersSticky) {
- return;
- }
-
- final int headerViewCount = mList.getHeaderViewsCount();
- int headerPosition = firstVisiblePosition - headerViewCount;
- if (mList.getChildCount() > 0) {
- View firstItem = mList.getChildAt(0);
- if (firstItem.getBottom() < stickyHeaderTop()) {
- headerPosition++;
- }
- }
-
- // It is not a mistake to call getFirstVisiblePosition() here.
- // Most of the time getFixedFirstVisibleItem() should be called
- // but that does not work great together with getChildAt()
- final boolean doesListHaveChildren = mList.getChildCount() != 0;
- final boolean isFirstViewBelowTop = doesListHaveChildren
- && mList.getFirstVisiblePosition() == 0
- && mList.getChildAt(0).getTop() >= stickyHeaderTop();
- final boolean isHeaderPositionOutsideAdapterRange = headerPosition > adapterCount - 1
- || headerPosition < 0;
- if (!doesListHaveChildren || isHeaderPositionOutsideAdapterRange || isFirstViewBelowTop) {
- clearHeader();
- return;
- }
-
- updateHeader(headerPosition);
- }
-
- private void updateHeader(int headerPosition) {
-
- // check if there is a new header should be sticky
- if (mHeaderPosition == null || mHeaderPosition != headerPosition) {
- mHeaderPosition = headerPosition;
- final long headerId = mAdapter.getHeaderId(headerPosition);
- if (mHeaderId == null || mHeaderId != headerId) {
- mHeaderId = headerId;
- final View header = mAdapter.getHeaderView(mHeaderPosition, mHeader, this);
- if (mHeader != header) {
- if (header == null) {
- throw new NullPointerException("header may not be null");
- }
- swapHeader(header);
- }
- ensureHeaderHasCorrectLayoutParams(mHeader);
- measureHeader(mHeader);
- if (mOnStickyHeaderChangedListener != null) {
- mOnStickyHeaderChangedListener.onStickyHeaderChanged(this, mHeader, headerPosition, mHeaderId);
- }
- // Reset mHeaderOffset to null ensuring
- // that it will be set on the header and
- // not skipped for performance reasons.
- mHeaderOffset = null;
- }
- }
-
- int headerOffset = stickyHeaderTop();
-
- // Calculate new header offset
- // Skip looking at the first view. it never matters because it always
- // results in a headerOffset = 0
- for (int i = 0; i < mList.getChildCount(); i++) {
- final View child = mList.getChildAt(i);
- final boolean doesChildHaveHeader = child instanceof WrapperView && ((WrapperView) child).hasHeader();
- final boolean isChildFooter = mList.containsFooterView(child);
- if (child.getTop() >= stickyHeaderTop() && (doesChildHaveHeader || isChildFooter)) {
- headerOffset = Math.min(child.getTop() - mHeader.getMeasuredHeight(), headerOffset);
- break;
- }
- }
-
- setHeaderOffet(headerOffset);
-
- if (!mIsDrawingListUnderStickyHeader) {
- mList.setTopClippingLength(mHeader.getMeasuredHeight()
- + mHeaderOffset);
- }
-
- updateHeaderVisibilities();
- }
-
- private void swapHeader(View newHeader) {
- if (mHeader != null) {
- removeView(mHeader);
- }
- mHeader = newHeader;
- addView(mHeader);
- if (mOnHeaderClickListener != null) {
- mHeader.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mOnHeaderClickListener.onHeaderClick(
- StickyListHeadersListView.this, mHeader,
- mHeaderPosition, mHeaderId, true);
- }
- });
- }
- mHeader.setClickable(true);
- }
-
- // hides the headers in the list under the sticky header.
- // Makes sure the jmui_other ones are showing
- private void updateHeaderVisibilities() {
- int top = stickyHeaderTop();
- int childCount = mList.getChildCount();
- for (int i = 0; i < childCount; i++) {
-
- // ensure child is a wrapper view
- View child = mList.getChildAt(i);
- if (!(child instanceof WrapperView)) {
- continue;
- }
-
- // ensure wrapper view child has a header
- WrapperView wrapperViewChild = (WrapperView) child;
- if (!wrapperViewChild.hasHeader()) {
- continue;
- }
-
- // update header views visibility
- View childHeader = wrapperViewChild.mHeader;
- if (wrapperViewChild.getTop() < top) {
- if (childHeader.getVisibility() != View.INVISIBLE) {
- childHeader.setVisibility(View.INVISIBLE);
- }
- } else {
- if (childHeader.getVisibility() != View.VISIBLE) {
- childHeader.setVisibility(View.VISIBLE);
- }
- }
- }
- }
-
- // Wrapper around setting the header offset in different ways depending on
- // the API version
- @SuppressLint("NewApi")
- private void setHeaderOffet(int offset) {
- if (mHeaderOffset == null || mHeaderOffset != offset) {
- mHeaderOffset = offset;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- mHeader.setTranslationY(mHeaderOffset);
- } else {
- MarginLayoutParams params = (MarginLayoutParams) mHeader.getLayoutParams();
- params.topMargin = mHeaderOffset;
- mHeader.setLayoutParams(params);
- }
- if (mOnStickyHeaderOffsetChangedListener != null) {
- mOnStickyHeaderOffsetChangedListener.onStickyHeaderOffsetChanged(this, mHeader, -mHeaderOffset);
- }
- }
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- int action = ev.getAction() & MotionEvent.ACTION_MASK;
- if (action == MotionEvent.ACTION_DOWN) {
- mDownY = ev.getY();
- mHeaderOwnsTouch = mHeader != null && mDownY <= mHeader.getHeight() + mHeaderOffset;
- }
-
- boolean handled;
- if (mHeaderOwnsTouch) {
- if (mHeader != null && Math.abs(mDownY - ev.getY()) <= mTouchSlop) {
- handled = mHeader.dispatchTouchEvent(ev);
- } else {
- if (mHeader != null) {
- MotionEvent cancelEvent = MotionEvent.obtain(ev);
- cancelEvent.setAction(MotionEvent.ACTION_CANCEL);
- mHeader.dispatchTouchEvent(cancelEvent);
- cancelEvent.recycle();
- }
-
- MotionEvent downEvent = MotionEvent.obtain(ev.getDownTime(), ev.getEventTime(), ev.getAction(), ev.getX(), mDownY, ev.getMetaState());
- downEvent.setAction(MotionEvent.ACTION_DOWN);
- handled = mList.dispatchTouchEvent(downEvent);
- downEvent.recycle();
- mHeaderOwnsTouch = false;
- }
- } else {
- handled = mList.dispatchTouchEvent(ev);
- }
-
- return handled;
- }
-
- private class AdapterWrapperDataSetObserver extends DataSetObserver {
-
- @Override
- public void onChanged() {
- clearHeader();
- }
-
- @Override
- public void onInvalidated() {
- clearHeader();
- }
-
- }
-
- private class WrapperListScrollListener implements OnScrollListener {
-
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- if (mOnScrollListenerDelegate != null) {
- mOnScrollListenerDelegate.onScroll(view, firstVisibleItem,
- visibleItemCount, totalItemCount);
- }
- updateOrClearHeader(mList.getFixedFirstVisibleItem());
- }
-
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- if (mOnScrollListenerDelegate != null) {
- mOnScrollListenerDelegate.onScrollStateChanged(view,
- scrollState);
- }
- }
-
- }
-
- private class WrapperViewListLifeCycleListener implements WrapperViewList.LifeCycleListener {
-
- @Override
- public void onDispatchDrawOccurred(Canvas canvas) {
- // onScroll is not called often at all before froyo
- // therefor we need to update the header here as well.
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) {
- updateOrClearHeader(mList.getFixedFirstVisibleItem());
- }
- if (mHeader != null) {
- if (mClippingToPadding) {
- canvas.save();
- canvas.clipRect(0, mPaddingTop, getRight(), getBottom());
- drawChild(canvas, mHeader, 0);
- canvas.restore();
- } else {
- drawChild(canvas, mHeader, 0);
- }
- }
- }
-
- }
-
- private class AdapterWrapperHeaderClickHandler implements
- AdapterWrapper.OnHeaderClickListener {
-
- @Override
- public void onHeaderClick(View header, int itemPosition, long headerId) {
- mOnHeaderClickListener.onHeaderClick(
- StickyListHeadersListView.this, header, itemPosition,
- headerId, false);
- }
-
- }
-
- private boolean isStartOfSection(int position) {
- return position == 0 || mAdapter.getHeaderId(position) != mAdapter.getHeaderId(position - 1);
- }
-
- public int getHeaderOverlap(int position) {
- boolean isStartOfSection = isStartOfSection(Math.max(0, position - getHeaderViewsCount()));
- if (!isStartOfSection) {
- View header = mAdapter.getHeaderView(position, null, mList);
- if (header == null) {
- throw new NullPointerException("header may not be null");
- }
- ensureHeaderHasCorrectLayoutParams(header);
- measureHeader(header);
- return header.getMeasuredHeight();
- }
- return 0;
- }
-
- private int stickyHeaderTop() {
- return mStickyHeaderTopOffset + (mClippingToPadding ? mPaddingTop : 0);
- }
-
- /* ---------- StickyListHeaders specific API ---------- */
-
- public void setAreHeadersSticky(boolean areHeadersSticky) {
- mAreHeadersSticky = areHeadersSticky;
- if (!areHeadersSticky) {
- clearHeader();
- } else {
- updateOrClearHeader(mList.getFixedFirstVisibleItem());
- }
- // invalidating the list will trigger dispatchDraw()
- mList.invalidate();
- }
-
- public boolean areHeadersSticky() {
- return mAreHeadersSticky;
- }
-
- /**
- * Use areHeadersSticky() method instead
- */
- @Deprecated
- public boolean getAreHeadersSticky() {
- return areHeadersSticky();
- }
-
- /**
- * @param stickyHeaderTopOffset The offset of the sticky header fom the top of the view
- */
- public void setStickyHeaderTopOffset(int stickyHeaderTopOffset) {
- mStickyHeaderTopOffset = stickyHeaderTopOffset;
- updateOrClearHeader(mList.getFixedFirstVisibleItem());
- }
-
- public int getStickyHeaderTopOffset() {
- return mStickyHeaderTopOffset;
- }
-
- public void setDrawingListUnderStickyHeader(
- boolean drawingListUnderStickyHeader) {
- mIsDrawingListUnderStickyHeader = drawingListUnderStickyHeader;
- // reset the top clipping length
- mList.setTopClippingLength(0);
- }
-
- public boolean isDrawingListUnderStickyHeader() {
- return mIsDrawingListUnderStickyHeader;
- }
-
- public void setOnHeaderClickListener(OnHeaderClickListener listener) {
- mOnHeaderClickListener = listener;
- if (mAdapter != null) {
- if (mOnHeaderClickListener != null) {
- mAdapter.setOnHeaderClickListener(new AdapterWrapperHeaderClickHandler());
-
- if (mHeader != null) {
- mHeader.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mOnHeaderClickListener.onHeaderClick(
- StickyListHeadersListView.this, mHeader,
- mHeaderPosition, mHeaderId, true);
- }
- });
- }
- } else {
- mAdapter.setOnHeaderClickListener(null);
- }
- }
- }
-
- public void setOnStickyHeaderOffsetChangedListener(OnStickyHeaderOffsetChangedListener listener) {
- mOnStickyHeaderOffsetChangedListener = listener;
- }
-
- public void setOnStickyHeaderChangedListener(OnStickyHeaderChangedListener listener) {
- mOnStickyHeaderChangedListener = listener;
- }
-
- public View getListChildAt(int index) {
- return mList.getChildAt(index);
- }
-
- public int getListChildCount() {
- return mList.getChildCount();
- }
-
- /**
- * Use the method with extreme caution!! Changing any values on the
- * underlying ListView might break everything.
- *
- * @return the ListView backing this view.
- */
- public ListView getWrappedList() {
- return mList;
- }
-
- private boolean requireSdkVersion(int versionCode) {
- if (Build.VERSION.SDK_INT < versionCode) {
- Log.e("StickyListHeaders", "Api lvl must be at least " + versionCode + " to call this method");
- return false;
- }
- return true;
- }
-
- /* ---------- ListView delegate methods ---------- */
-
- public void setAdapter(StickyListHeadersAdapter adapter) {
- if (adapter == null) {
- if (mAdapter instanceof SectionIndexerAdapterWrapper) {
- ((SectionIndexerAdapterWrapper) mAdapter).mSectionIndexerDelegate = null;
- }
- if (mAdapter != null) {
- mAdapter.mDelegate = null;
- }
- mList.setAdapter(null);
- clearHeader();
- return;
- }
- if (mAdapter != null) {
- mAdapter.unregisterDataSetObserver(mDataSetObserver);
- }
-
- if (adapter instanceof SectionIndexer) {
- mAdapter = new SectionIndexerAdapterWrapper(getContext(), adapter);
- } else {
- mAdapter = new AdapterWrapper(getContext(), adapter);
- }
- mDataSetObserver = new AdapterWrapperDataSetObserver();
- mAdapter.registerDataSetObserver(mDataSetObserver);
-
- if (mOnHeaderClickListener != null) {
- mAdapter.setOnHeaderClickListener(new AdapterWrapperHeaderClickHandler());
- } else {
- mAdapter.setOnHeaderClickListener(null);
- }
-
- mAdapter.setDivider(mDivider, mDividerHeight);
-
- mList.setAdapter(mAdapter);
- clearHeader();
- }
-
- public StickyListHeadersAdapter getAdapter() {
- return mAdapter == null ? null : mAdapter.mDelegate;
- }
-
- public void setDivider(Drawable divider) {
- mDivider = divider;
- if (mAdapter != null) {
- mAdapter.setDivider(mDivider, mDividerHeight);
- }
- }
-
- public void setDividerHeight(int dividerHeight) {
- mDividerHeight = dividerHeight;
- if (mAdapter != null) {
- mAdapter.setDivider(mDivider, mDividerHeight);
- }
- }
-
- public Drawable getDivider() {
- return mDivider;
- }
-
- public int getDividerHeight() {
- return mDividerHeight;
- }
-
- public void setOnScrollListener(OnScrollListener onScrollListener) {
- mOnScrollListenerDelegate = onScrollListener;
- }
-
- @Override
- public void setOnTouchListener(final OnTouchListener l) {
- if (l != null) {
- mList.setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return l.onTouch(StickyListHeadersListView.this, event);
- }
- });
- } else {
- mList.setOnTouchListener(null);
- }
- }
-
- public void setOnItemClickListener(OnItemClickListener listener) {
- mList.setOnItemClickListener(listener);
- }
-
- public void setOnItemLongClickListener(OnItemLongClickListener listener) {
- mList.setOnItemLongClickListener(listener);
- }
-
- public void addHeaderView(View v, Object data, boolean isSelectable) {
- mList.addHeaderView(v, data, isSelectable);
- }
-
- public void addHeaderView(View v) {
- mList.addHeaderView(v);
- }
-
- public void removeHeaderView(View v) {
- mList.removeHeaderView(v);
- }
-
- public int getHeaderViewsCount() {
- return mList.getHeaderViewsCount();
- }
-
- public void addFooterView(View v, Object data, boolean isSelectable) {
- mList.addFooterView(v, data, isSelectable);
- }
-
- public void addFooterView(View v) {
- mList.addFooterView(v);
- }
-
- public void removeFooterView(View v) {
- mList.removeFooterView(v);
- }
-
- public int getFooterViewsCount() {
- return mList.getFooterViewsCount();
- }
-
- public void setEmptyView(View v) {
- mList.setEmptyView(v);
- }
-
- public View getEmptyView() {
- return mList.getEmptyView();
- }
-
- @Override
- public boolean isVerticalScrollBarEnabled() {
- return mList.isVerticalScrollBarEnabled();
- }
-
- @Override
- public boolean isHorizontalScrollBarEnabled() {
- return mList.isHorizontalScrollBarEnabled();
- }
-
- @Override
- public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) {
- mList.setVerticalScrollBarEnabled(verticalScrollBarEnabled);
- }
-
- @Override
- public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) {
- mList.setHorizontalScrollBarEnabled(horizontalScrollBarEnabled);
- }
-
- @Override
- @TargetApi(Build.VERSION_CODES.GINGERBREAD)
- public int getOverScrollMode() {
- if (requireSdkVersion(Build.VERSION_CODES.GINGERBREAD)) {
- return mList.getOverScrollMode();
- }
- return 0;
- }
-
- @Override
- @TargetApi(Build.VERSION_CODES.GINGERBREAD)
- public void setOverScrollMode(int mode) {
- if (requireSdkVersion(Build.VERSION_CODES.GINGERBREAD)) {
- if (mList != null) {
- mList.setOverScrollMode(mode);
- }
- }
- }
-
- @TargetApi(Build.VERSION_CODES.FROYO)
- public void smoothScrollBy(int distance, int duration) {
- if (requireSdkVersion(Build.VERSION_CODES.FROYO)) {
- mList.smoothScrollBy(distance, duration);
- }
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public void smoothScrollByOffset(int offset) {
- if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) {
- mList.smoothScrollByOffset(offset);
- }
- }
-
- @SuppressLint("NewApi")
- @TargetApi(Build.VERSION_CODES.FROYO)
- public void smoothScrollToPosition(int position) {
- if (requireSdkVersion(Build.VERSION_CODES.FROYO)) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
- mList.smoothScrollToPosition(position);
- } else {
- int offset = mAdapter == null ? 0 : getHeaderOverlap(position);
- offset -= mClippingToPadding ? 0 : mPaddingTop;
- mList.smoothScrollToPositionFromTop(position, offset);
- }
- }
- }
-
- @TargetApi(Build.VERSION_CODES.FROYO)
- public void smoothScrollToPosition(int position, int boundPosition) {
- if (requireSdkVersion(Build.VERSION_CODES.FROYO)) {
- mList.smoothScrollToPosition(position, boundPosition);
- }
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public void smoothScrollToPositionFromTop(int position, int offset) {
- if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) {
- offset += mAdapter == null ? 0 : getHeaderOverlap(position);
- offset -= mClippingToPadding ? 0 : mPaddingTop;
- mList.smoothScrollToPositionFromTop(position, offset);
- }
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public void smoothScrollToPositionFromTop(int position, int offset,
- int duration) {
- if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) {
- offset += mAdapter == null ? 0 : getHeaderOverlap(position);
- offset -= mClippingToPadding ? 0 : mPaddingTop;
- mList.smoothScrollToPositionFromTop(position, offset, duration);
- }
- }
-
- public void setSelection(int position) {
- setSelectionFromTop(position, 0);
- }
-
- public void setSelectionAfterHeaderView() {
- mList.setSelectionAfterHeaderView();
- }
-
- public void setSelectionFromTop(int position, int y) {
- y += mAdapter == null ? 0 : getHeaderOverlap(position);
- y -= mClippingToPadding ? 0 : mPaddingTop;
- mList.setSelectionFromTop(position, y);
- }
-
- public void setSelector(Drawable sel) {
- mList.setSelector(sel);
- }
-
- public void setSelector(int resID) {
- mList.setSelector(resID);
- }
-
- public int getFirstVisiblePosition() {
- return mList.getFirstVisiblePosition();
- }
-
- public int getLastVisiblePosition() {
- return mList.getLastVisiblePosition();
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public void setChoiceMode(int choiceMode) {
- mList.setChoiceMode(choiceMode);
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public void setItemChecked(int position, boolean value) {
- mList.setItemChecked(position, value);
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public int getCheckedItemCount() {
- if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) {
- return mList.getCheckedItemCount();
- }
- return 0;
- }
-
- @TargetApi(11)
- public long[] getCheckedItemIds() {
- if (requireSdkVersion(Build.VERSION_CODES.FROYO)) {
- return mList.getCheckedItemIds();
- }
- return null;
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public int getCheckedItemPosition() {
- return mList.getCheckedItemPosition();
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public SparseBooleanArray getCheckedItemPositions() {
- return mList.getCheckedItemPositions();
- }
-
- public int getCount() {
- return mList.getCount();
- }
-
- public Object getItemAtPosition(int position) {
- return mList.getItemAtPosition(position);
- }
-
- public long getItemIdAtPosition(int position) {
- return mList.getItemIdAtPosition(position);
- }
-
- @Override
- public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) {
- mList.setOnCreateContextMenuListener(l);
- }
-
- @Override
- public boolean showContextMenu() {
- return mList.showContextMenu();
- }
-
- public void invalidateViews() {
- mList.invalidateViews();
- }
-
- @Override
- public void setClipToPadding(boolean clipToPadding) {
- if (mList != null) {
- mList.setClipToPadding(clipToPadding);
- }
- mClippingToPadding = clipToPadding;
- }
-
- @Override
- public void setPadding(int left, int top, int right, int bottom) {
- mPaddingLeft = left;
- mPaddingTop = top;
- mPaddingRight = right;
- mPaddingBottom = bottom;
-
- if (mList != null) {
- mList.setPadding(left, top, right, bottom);
- }
- super.setPadding(0, 0, 0, 0);
- requestLayout();
- }
-
- /*
- * Overrides an @hide method in View
- */
- protected void recomputePadding() {
- setPadding(mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom);
- }
-
- @Override
- public int getPaddingLeft() {
- return mPaddingLeft;
- }
-
- @Override
- public int getPaddingTop() {
- return mPaddingTop;
- }
-
- @Override
- public int getPaddingRight() {
- return mPaddingRight;
- }
-
- @Override
- public int getPaddingBottom() {
- return mPaddingBottom;
- }
-
- public void setFastScrollEnabled(boolean fastScrollEnabled) {
- mList.setFastScrollEnabled(fastScrollEnabled);
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public void setFastScrollAlwaysVisible(boolean alwaysVisible) {
- if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) {
- mList.setFastScrollAlwaysVisible(alwaysVisible);
- }
- }
-
- /**
- * @return true if the fast scroller will always show. False on pre-Honeycomb devices.
- * @see AbsListView#isFastScrollAlwaysVisible()
- */
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public boolean isFastScrollAlwaysVisible() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
- return false;
- }
- return mList.isFastScrollAlwaysVisible();
- }
-
- public void setScrollBarStyle(int style) {
- mList.setScrollBarStyle(style);
- }
-
- public int getScrollBarStyle() {
- return mList.getScrollBarStyle();
- }
-
- public int getPositionForView(View view) {
- return mList.getPositionForView(view);
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public void setMultiChoiceModeListener(MultiChoiceModeListener listener) {
- if (requireSdkVersion(Build.VERSION_CODES.HONEYCOMB)) {
- mList.setMultiChoiceModeListener(listener);
- }
- }
-
- @Override
- public Parcelable onSaveInstanceState() {
- Parcelable superState = super.onSaveInstanceState();
- if (superState != BaseSavedState.EMPTY_STATE) {
- throw new IllegalStateException("Handling non empty state of parent class is not implemented");
- }
- return mList.onSaveInstanceState();
- }
-
- @Override
- public void onRestoreInstanceState(Parcelable state) {
- super.onRestoreInstanceState(BaseSavedState.EMPTY_STATE);
- mList.onRestoreInstanceState(state);
- }
-
- @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
- @Override
- public boolean canScrollVertically(int direction) {
- return mList.canScrollVertically(direction);
- }
-
- public void setTranscriptMode(int mode) {
- mList.setTranscriptMode(mode);
- }
-
- public void setBlockLayoutChildren(boolean blockLayoutChildren) {
- mList.setBlockLayoutChildren(blockLayoutChildren);
- }
-
- public void setStackFromBottom(boolean stackFromBottom) {
- mList.setStackFromBottom(stackFromBottom);
- }
-
- public boolean isStackFromBottom() {
- return mList.isStackFromBottom();
- }
-}
diff --git a/chatapp/src/main/res/drawable-xxhdpi/chat_room_avatar.png b/chatapp/src/main/res/drawable-xxhdpi/chat_room_avatar.png
new file mode 100644
index 00000000..495ac783
Binary files /dev/null and b/chatapp/src/main/res/drawable-xxhdpi/chat_room_avatar.png differ
diff --git a/chatapp/src/main/res/drawable-xxhdpi/conversation_normal.png b/chatapp/src/main/res/drawable-xxhdpi/conversation_normal.png
new file mode 100644
index 00000000..b333ef48
Binary files /dev/null and b/chatapp/src/main/res/drawable-xxhdpi/conversation_normal.png differ
diff --git a/chatapp/src/main/res/drawable-xxhdpi/conversation_press.png b/chatapp/src/main/res/drawable-xxhdpi/conversation_press.png
new file mode 100644
index 00000000..e822a4f3
Binary files /dev/null and b/chatapp/src/main/res/drawable-xxhdpi/conversation_press.png differ
diff --git a/chatapp/src/main/res/drawable-xxhdpi/open_group.png b/chatapp/src/main/res/drawable-xxhdpi/open_group.png
new file mode 100644
index 00000000..efd6b7cf
Binary files /dev/null and b/chatapp/src/main/res/drawable-xxhdpi/open_group.png differ
diff --git a/chatapp/src/main/res/drawable-xxhdpi/update_avatar.png b/chatapp/src/main/res/drawable-xxhdpi/update_avatar.png
new file mode 100644
index 00000000..e7fcc26a
Binary files /dev/null and b/chatapp/src/main/res/drawable-xxhdpi/update_avatar.png differ
diff --git a/chatapp/src/main/res/drawable/actionbar_conversation_bg.xml b/chatapp/src/main/res/drawable/actionbar_conversation_bg.xml
new file mode 100644
index 00000000..947e6ab2
--- /dev/null
+++ b/chatapp/src/main/res/drawable/actionbar_conversation_bg.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/actionbar_me_drawable_bg.xml b/chatapp/src/main/res/drawable/actionbar_me_drawable_bg.xml
index 4928783a..6993afab 100644
--- a/chatapp/src/main/res/drawable/actionbar_me_drawable_bg.xml
+++ b/chatapp/src/main/res/drawable/actionbar_me_drawable_bg.xml
@@ -1,7 +1,6 @@
-
-
-
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/border_bg.xml b/chatapp/src/main/res/drawable/border_bg.xml
new file mode 100644
index 00000000..73510c93
--- /dev/null
+++ b/chatapp/src/main/res/drawable/border_bg.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/bottom_line.xml b/chatapp/src/main/res/drawable/bottom_line.xml
new file mode 100644
index 00000000..d73d1364
--- /dev/null
+++ b/chatapp/src/main/res/drawable/bottom_line.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/bottom_line_normal.xml b/chatapp/src/main/res/drawable/bottom_line_normal.xml
new file mode 100644
index 00000000..c304cbe7
--- /dev/null
+++ b/chatapp/src/main/res/drawable/bottom_line_normal.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/edittext.xml b/chatapp/src/main/res/drawable/edittext.xml
index fc962c21..c8888da8 100644
--- a/chatapp/src/main/res/drawable/edittext.xml
+++ b/chatapp/src/main/res/drawable/edittext.xml
@@ -1,4 +1,3 @@
-
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/jmui_remove_btn_bg.xml b/chatapp/src/main/res/drawable/jmui_remove_btn_bg.xml
new file mode 100644
index 00000000..0e453255
--- /dev/null
+++ b/chatapp/src/main/res/drawable/jmui_remove_btn_bg.xml
@@ -0,0 +1,8 @@
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/selector_home_title_line.xml b/chatapp/src/main/res/drawable/selector_home_title_line.xml
new file mode 100644
index 00000000..dba6c6ec
--- /dev/null
+++ b/chatapp/src/main/res/drawable/selector_home_title_line.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/switch_thumb.xml b/chatapp/src/main/res/drawable/switch_thumb.xml
new file mode 100644
index 00000000..80ae6554
--- /dev/null
+++ b/chatapp/src/main/res/drawable/switch_thumb.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/switch_track.xml b/chatapp/src/main/res/drawable/switch_track.xml
new file mode 100644
index 00000000..c211ed07
--- /dev/null
+++ b/chatapp/src/main/res/drawable/switch_track.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/switch_track_off.xml b/chatapp/src/main/res/drawable/switch_track_off.xml
new file mode 100644
index 00000000..6a6a7a4d
--- /dev/null
+++ b/chatapp/src/main/res/drawable/switch_track_off.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/switch_track_on.xml b/chatapp/src/main/res/drawable/switch_track_on.xml
new file mode 100644
index 00000000..7292eefc
--- /dev/null
+++ b/chatapp/src/main/res/drawable/switch_track_on.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/drawable/text_selector.xml b/chatapp/src/main/res/drawable/text_selector.xml
new file mode 100644
index 00000000..6e2a83ec
--- /dev/null
+++ b/chatapp/src/main/res/drawable/text_selector.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_apply_group_info.xml b/chatapp/src/main/res/layout/activity_apply_group_info.xml
new file mode 100644
index 00000000..cf50b019
--- /dev/null
+++ b/chatapp/src/main/res/layout/activity_apply_group_info.xml
@@ -0,0 +1,255 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_chat.xml b/chatapp/src/main/res/layout/activity_chat.xml
index b1dc4b4c..4c82d5c0 100644
--- a/chatapp/src/main/res/layout/activity_chat.xml
+++ b/chatapp/src/main/res/layout/activity_chat.xml
@@ -45,7 +45,6 @@
android:layout_height="wrap_content"
android:maxWidth="190dp"
android:singleLine="true"
- android:text="昵称"
android:textColor="#FFFFFF"
android:textSize="18sp"/>
@@ -56,7 +55,6 @@
android:singleLine="true"
android:textColor="#FFFFFF"
android:textSize="20sp"/>
-
+ android:gravity="center_horizontal"
+ android:paddingBottom="19dp">
+
+
@@ -82,7 +88,9 @@
android:text="群头像"/>
+ style="@style/ChatDetailArrow"
+ android:layout_marginStart="11dp"
+ android:layout_toEndOf="@+id/iv_groupAvatar"/>
@@ -119,7 +127,7 @@
@@ -153,7 +161,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/chatapp/src/main/res/layout/activity_chat_room_detail.xml b/chatapp/src/main/res/layout/activity_chat_room_detail.xml
new file mode 100644
index 00000000..42c4779b
--- /dev/null
+++ b/chatapp/src/main/res/layout/activity_chat_room_detail.xml
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_chat_room_info.xml b/chatapp/src/main/res/layout/activity_chat_room_info.xml
new file mode 100644
index 00000000..8f0215aa
--- /dev/null
+++ b/chatapp/src/main/res/layout/activity_chat_room_info.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_chat_room_keeper.xml b/chatapp/src/main/res/layout/activity_chat_room_keeper.xml
new file mode 100644
index 00000000..602f87de
--- /dev/null
+++ b/chatapp/src/main/res/layout/activity_chat_room_keeper.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/chatapp/src/main/res/layout/activity_choose_at_member.xml b/chatapp/src/main/res/layout/activity_choose_at_member.xml
index 4bf1606c..c06b49fb 100644
--- a/chatapp/src/main/res/layout/activity_choose_at_member.xml
+++ b/chatapp/src/main/res/layout/activity_choose_at_member.xml
@@ -60,7 +60,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
@@ -132,13 +133,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_group_member_list.xml b/chatapp/src/main/res/layout/activity_group_member_list.xml
new file mode 100644
index 00000000..b8cee3bc
--- /dev/null
+++ b/chatapp/src/main/res/layout/activity_group_member_list.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_main.xml b/chatapp/src/main/res/layout/activity_main.xml
index 95470f6b..4ef40f43 100644
--- a/chatapp/src/main/res/layout/activity_main.xml
+++ b/chatapp/src/main/res/layout/activity_main.xml
@@ -25,25 +25,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_search_chat_room.xml b/chatapp/src/main/res/layout/activity_search_chat_room.xml
new file mode 100644
index 00000000..87704c37
--- /dev/null
+++ b/chatapp/src/main/res/layout/activity_search_chat_room.xml
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_search_for_chat_room.xml b/chatapp/src/main/res/layout/activity_search_for_chat_room.xml
new file mode 100644
index 00000000..ffb5654a
--- /dev/null
+++ b/chatapp/src/main/res/layout/activity_search_for_chat_room.xml
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_select_create_group_type.xml b/chatapp/src/main/res/layout/activity_select_create_group_type.xml
new file mode 100644
index 00000000..e6226dfa
--- /dev/null
+++ b/chatapp/src/main/res/layout/activity_select_create_group_type.xml
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_set_group_silence.xml b/chatapp/src/main/res/layout/activity_set_group_silence.xml
new file mode 100644
index 00000000..cd86b9fe
--- /dev/null
+++ b/chatapp/src/main/res/layout/activity_set_group_silence.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_silence_users.xml b/chatapp/src/main/res/layout/activity_silence_users.xml
new file mode 100644
index 00000000..38cd2d7d
--- /dev/null
+++ b/chatapp/src/main/res/layout/activity_silence_users.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/activity_verification_message.xml b/chatapp/src/main/res/layout/activity_verification_message.xml
new file mode 100644
index 00000000..30a94ddd
--- /dev/null
+++ b/chatapp/src/main/res/layout/activity_verification_message.xml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/document_file.xml b/chatapp/src/main/res/layout/document_file.xml
index f865668f..fb0f6225 100644
--- a/chatapp/src/main/res/layout/document_file.xml
+++ b/chatapp/src/main/res/layout/document_file.xml
@@ -8,7 +8,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
-
+ android:background="@drawable/launch_single">
-
+
-
+ android:background="@drawable/launch_group">
-
+
-
+ android:background="@drawable/launch_friend">
-
-
+
+
+
+
+
+
+
+
+
+ android:background="@drawable/launch_friend">
-
+
diff --git a/chatapp/src/main/res/layout/fragment_chat_room.xml b/chatapp/src/main/res/layout/fragment_chat_room.xml
new file mode 100644
index 00000000..971d998f
--- /dev/null
+++ b/chatapp/src/main/res/layout/fragment_chat_room.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/fragment_contacts.xml b/chatapp/src/main/res/layout/fragment_contacts.xml
index d67ccb64..7ae41a7d 100644
--- a/chatapp/src/main/res/layout/fragment_contacts.xml
+++ b/chatapp/src/main/res/layout/fragment_contacts.xml
@@ -39,7 +39,7 @@
android:layout_height="match_parent">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/header_list_group_member.xml b/chatapp/src/main/res/layout/header_list_group_member.xml
new file mode 100644
index 00000000..9baf6b3a
--- /dev/null
+++ b/chatapp/src/main/res/layout/header_list_group_member.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/item_chat_room.xml b/chatapp/src/main/res/layout/item_chat_room.xml
new file mode 100644
index 00000000..4dace029
--- /dev/null
+++ b/chatapp/src/main/res/layout/item_chat_room.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/item_chat_room_keeper.xml b/chatapp/src/main/res/layout/item_chat_room_keeper.xml
new file mode 100644
index 00000000..d6a7b30a
--- /dev/null
+++ b/chatapp/src/main/res/layout/item_chat_room_keeper.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/chatapp/src/main/res/layout/item_chatroom_avatar.xml b/chatapp/src/main/res/layout/item_chatroom_avatar.xml
new file mode 100644
index 00000000..292b6b94
--- /dev/null
+++ b/chatapp/src/main/res/layout/item_chatroom_avatar.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/chatapp/src/main/res/layout/item_conv_list.xml b/chatapp/src/main/res/layout/item_conv_list.xml
index 04be9e11..f9aad83c 100644
--- a/chatapp/src/main/res/layout/item_conv_list.xml
+++ b/chatapp/src/main/res/layout/item_conv_list.xml
@@ -137,16 +137,31 @@
-
+ android:layout_below="@+id/title_layout">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/item_group_normal_recomend.xml b/chatapp/src/main/res/layout/item_group_normal_recomend.xml
new file mode 100644
index 00000000..e50ad5b8
--- /dev/null
+++ b/chatapp/src/main/res/layout/item_group_normal_recomend.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/item_group_owner_recomend.xml b/chatapp/src/main/res/layout/item_group_owner_recomend.xml
new file mode 100644
index 00000000..4af2d5e4
--- /dev/null
+++ b/chatapp/src/main/res/layout/item_group_owner_recomend.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/item_refuse_group.xml b/chatapp/src/main/res/layout/item_refuse_group.xml
new file mode 100644
index 00000000..9f805d5f
--- /dev/null
+++ b/chatapp/src/main/res/layout/item_refuse_group.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/item_search.xml b/chatapp/src/main/res/layout/item_search.xml
index 6fd82ed0..bf26531e 100644
--- a/chatapp/src/main/res/layout/item_search.xml
+++ b/chatapp/src/main/res/layout/item_search.xml
@@ -5,35 +5,32 @@
android:orientation="vertical">
+ android:layout_height="33.33dp"
+ android:background="#fff"
+ android:gravity="center">
-
-
-
-
+ android:layout_gravity="center"
+ android:paddingRight="10.17dp"
+ android:src="@drawable/search1"/>
-
-
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/item_silence_member.xml b/chatapp/src/main/res/layout/item_silence_member.xml
new file mode 100644
index 00000000..4eb798a0
--- /dev/null
+++ b/chatapp/src/main/res/layout/item_silence_member.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/list_item.xml b/chatapp/src/main/res/layout/list_item.xml
deleted file mode 100644
index 3a758812..00000000
--- a/chatapp/src/main/res/layout/list_item.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/load_complete.xml b/chatapp/src/main/res/layout/load_complete.xml
new file mode 100644
index 00000000..08bd616f
--- /dev/null
+++ b/chatapp/src/main/res/layout/load_complete.xml
@@ -0,0 +1,12 @@
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/verification_friend.xml b/chatapp/src/main/res/layout/verification_friend.xml
new file mode 100644
index 00000000..17a2b85e
--- /dev/null
+++ b/chatapp/src/main/res/layout/verification_friend.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/verification_group.xml b/chatapp/src/main/res/layout/verification_group.xml
new file mode 100644
index 00000000..12363863
--- /dev/null
+++ b/chatapp/src/main/res/layout/verification_group.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chatapp/src/main/res/layout/view_dialog_select.xml b/chatapp/src/main/res/layout/view_dialog_select.xml
index fc95e937..955c3ebc 100644
--- a/chatapp/src/main/res/layout/view_dialog_select.xml
+++ b/chatapp/src/main/res/layout/view_dialog_select.xml
@@ -24,9 +24,9 @@
android:layout_width="match_parent"
android:dividerHeight="0.5dp"
android:divider="#DAD9DB"
- android:layout_marginTop="5dip"
android:listSelector="@android:color/transparent"
android:cacheColorHint="@android:color/transparent"
+ android:layout_marginTop="5dip"
android:layout_height="wrap_content" >
diff --git a/chatapp/src/main/res/values/strings.xml b/chatapp/src/main/res/values/strings.xml
index a6fd8677..42654d3c 100644
--- a/chatapp/src/main/res/values/strings.xml
+++ b/chatapp/src/main/res/values/strings.xml
@@ -45,6 +45,7 @@
跨应用
会话
通讯录
+ 聊天室
我
邮箱/用户名/ID
搜索
@@ -411,5 +412,14 @@
条形码扫描
返回
将取景框对准二维码,即可自动扫描
+ 当前版本不支持此消息类型
+ 没有更多数据啦
+
+
+ 聊天室名称
+ 聊天室介绍
+ 房主
+ 管理员
+ 退出聊天室
diff --git a/chatapp/src/main/res/values/styles.xml b/chatapp/src/main/res/values/styles.xml
index 0948fc12..9b059871 100644
--- a/chatapp/src/main/res/values/styles.xml
+++ b/chatapp/src/main/res/values/styles.xml
@@ -21,6 +21,7 @@
- true
- @null
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -166,7 +183,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/emoji/.gitignore b/emoji/.gitignore
new file mode 100644
index 00000000..8b0bd4d0
--- /dev/null
+++ b/emoji/.gitignore
@@ -0,0 +1 @@
+/reclib-emoji/build
diff --git a/emoji/build.gradle b/emoji/build.gradle
new file mode 100644
index 00000000..f76e10dc
--- /dev/null
+++ b/emoji/build.gradle
@@ -0,0 +1,15 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 22
+ buildToolsVersion '28.0.3'
+
+ defaultConfig {
+ minSdkVersion 9
+ targetSdkVersion 22
+ }
+}
+
+dependencies {
+ implementation 'com.android.support:support-v4:22.1.1'
+}
\ No newline at end of file
diff --git a/emoji/proguard-rules.pro b/emoji/proguard-rules.pro
new file mode 100644
index 00000000..c730a3b5
--- /dev/null
+++ b/emoji/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/sj/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/emoji/src/main/AndroidManifest.xml b/emoji/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..629d02c7
--- /dev/null
+++ b/emoji/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/emoji/src/main/java/com/sj/emoji/DefEmoticons.java b/emoji/src/main/java/com/sj/emoji/DefEmoticons.java
new file mode 100644
index 00000000..728b7b79
--- /dev/null
+++ b/emoji/src/main/java/com/sj/emoji/DefEmoticons.java
@@ -0,0 +1,92 @@
+package com.sj.emoji;
+
+import com.sj.emoji.R;
+
+/**
+ * Created by sj on 16/3/22.
+ */
+public class DefEmoticons {
+
+ public static final EmojiBean[] sEmojiArray = {
+ new EmojiBean(R.mipmap.emoji_0x1f604, EmojiParse.fromCodePoint(0x1f604)),
+ new EmojiBean(R.mipmap.emoji_0x1f603, EmojiParse.fromCodePoint(0x1f603)),
+ new EmojiBean(R.mipmap.emoji_0x1f60a, EmojiParse.fromCodePoint(0x1f60a)),
+ new EmojiBean(R.mipmap.emoji_0x1f609, EmojiParse.fromCodePoint(0x1f609)),
+ new EmojiBean(R.mipmap.emoji_0x1f60d, EmojiParse.fromCodePoint(0x1f60d)),
+ new EmojiBean(R.mipmap.emoji_0x1f618, EmojiParse.fromCodePoint(0x1f618)),
+ new EmojiBean(R.mipmap.emoji_0x1f61a, EmojiParse.fromCodePoint(0x1f61a)),
+ new EmojiBean(R.mipmap.emoji_0x1f61c, EmojiParse.fromCodePoint(0x1f61c)),
+ new EmojiBean(R.mipmap.emoji_0x1f61d, EmojiParse.fromCodePoint(0x1f61d)),
+ new EmojiBean(R.mipmap.emoji_0x1f633, EmojiParse.fromCodePoint(0x1f633)),
+ new EmojiBean(R.mipmap.emoji_0x1f601, EmojiParse.fromCodePoint(0x1f601)),
+ new EmojiBean(R.mipmap.emoji_0x1f614, EmojiParse.fromCodePoint(0x1f614)),
+ new EmojiBean(R.mipmap.emoji_0x1f60c, EmojiParse.fromCodePoint(0x1f60c)),
+ new EmojiBean(R.mipmap.emoji_0x1f612, EmojiParse.fromCodePoint(0x1f612)),
+ new EmojiBean(R.mipmap.emoji_0x1f61e, EmojiParse.fromCodePoint(0x1f61e)),
+ new EmojiBean(R.mipmap.emoji_0x1f623, EmojiParse.fromCodePoint(0x1f623)),
+ new EmojiBean(R.mipmap.emoji_0x1f622, EmojiParse.fromCodePoint(0x1f622)),
+ new EmojiBean(R.mipmap.emoji_0x1f602, EmojiParse.fromCodePoint(0x1f602)),
+ new EmojiBean(R.mipmap.emoji_0x1f62d, EmojiParse.fromCodePoint(0x1f62d)),
+ new EmojiBean(R.mipmap.emoji_0x1f62a, EmojiParse.fromCodePoint(0x1f62a)),
+ new EmojiBean(R.mipmap.emoji_0x1f625, EmojiParse.fromCodePoint(0x1f625)),
+ new EmojiBean(R.mipmap.emoji_0x1f630, EmojiParse.fromCodePoint(0x1f630)),
+ new EmojiBean(R.mipmap.emoji_0x1f613, EmojiParse.fromCodePoint(0x1f613)),
+ new EmojiBean(R.mipmap.emoji_0x1f628, EmojiParse.fromCodePoint(0x1f628)),
+ new EmojiBean(R.mipmap.emoji_0x1f631, EmojiParse.fromCodePoint(0x1f631)),
+ new EmojiBean(R.mipmap.emoji_0x1f620, EmojiParse.fromCodePoint(0x1f620)),
+ new EmojiBean(R.mipmap.emoji_0x1f621, EmojiParse.fromCodePoint(0x1f621)),
+ new EmojiBean(R.mipmap.emoji_0x1f616, EmojiParse.fromCodePoint(0x1f616)),
+ new EmojiBean(R.mipmap.emoji_0x1f637, EmojiParse.fromCodePoint(0x1f637)),
+ new EmojiBean(R.mipmap.emoji_0x1f632, EmojiParse.fromCodePoint(0x1f632)),
+ new EmojiBean(R.mipmap.emoji_0x1f47f, EmojiParse.fromCodePoint(0x1f47f)),
+ new EmojiBean(R.mipmap.emoji_0x1f60f, EmojiParse.fromCodePoint(0x1f60f)),
+ new EmojiBean(R.mipmap.emoji_0x1f466, EmojiParse.fromCodePoint(0x1f466)),
+ new EmojiBean(R.mipmap.emoji_0x1f467, EmojiParse.fromCodePoint(0x1f467)),
+ new EmojiBean(R.mipmap.emoji_0x1f468, EmojiParse.fromCodePoint(0x1f468)),
+ new EmojiBean(R.mipmap.emoji_0x1f469, EmojiParse.fromCodePoint(0x1f469)),
+ new EmojiBean(R.mipmap.emoji_0x1f31f, EmojiParse.fromCodePoint(0x1f31f)),
+ new EmojiBean(R.mipmap.emoji_0x1f444, EmojiParse.fromCodePoint(0x1f444)),
+ new EmojiBean(R.mipmap.emoji_0x1f44d, EmojiParse.fromCodePoint(0x1f44d)),
+ new EmojiBean(R.mipmap.emoji_0x1f44e, EmojiParse.fromCodePoint(0x1f44e)),
+ new EmojiBean(R.mipmap.emoji_0x1f44c, EmojiParse.fromCodePoint(0x1f44c)),
+ new EmojiBean(R.mipmap.emoji_0x1f44a, EmojiParse.fromCodePoint(0x1f44a)),
+ new EmojiBean(R.mipmap.emoji_0x270a, EmojiParse.fromChar((char) 0x270a)),
+ new EmojiBean(R.mipmap.emoji_0x270c, EmojiParse.fromChar((char) 0x270c)),
+ new EmojiBean(R.mipmap.emoji_0x1f446, EmojiParse.fromCodePoint(0x1f446)),
+ new EmojiBean(R.mipmap.emoji_0x1f447, EmojiParse.fromCodePoint(0x1f447)),
+ new EmojiBean(R.mipmap.emoji_0x1f449, EmojiParse.fromCodePoint(0x1f449)),
+ new EmojiBean(R.mipmap.emoji_0x1f448, EmojiParse.fromCodePoint(0x1f448)),
+ new EmojiBean(R.mipmap.emoji_0x1f64f, EmojiParse.fromCodePoint(0x1f64f)),
+ new EmojiBean(R.mipmap.emoji_0x1f44f, EmojiParse.fromCodePoint(0x1f44f)),
+ new EmojiBean(R.mipmap.emoji_0x1f4aa, EmojiParse.fromCodePoint(0x1f4aa)),
+ new EmojiBean(R.mipmap.emoji_0x1f457, EmojiParse.fromCodePoint(0x1f457)),
+ new EmojiBean(R.mipmap.emoji_0x1f380, EmojiParse.fromCodePoint(0x1f380)),
+ new EmojiBean(R.mipmap.emoji_0x2764, EmojiParse.fromChar((char) 0x2764)),
+ new EmojiBean(R.mipmap.emoji_0x1f494, EmojiParse.fromCodePoint(0x1f494)),
+ new EmojiBean(R.mipmap.emoji_0x1f48e, EmojiParse.fromCodePoint(0x1f48e)),
+ new EmojiBean(R.mipmap.emoji_0x1f436, EmojiParse.fromCodePoint(0x1f436)),
+ new EmojiBean(R.mipmap.emoji_0x1f431, EmojiParse.fromCodePoint(0x1f431)),
+ new EmojiBean(R.mipmap.emoji_0x1f339, EmojiParse.fromCodePoint(0x1f339)),
+ new EmojiBean(R.mipmap.emoji_0x1f33b, EmojiParse.fromCodePoint(0x1f33b)),
+ new EmojiBean(R.mipmap.emoji_0x1f341, EmojiParse.fromCodePoint(0x1f341)),
+ new EmojiBean(R.mipmap.emoji_0x1f343, EmojiParse.fromCodePoint(0x1f343)),
+ new EmojiBean(R.mipmap.emoji_0x1f319, EmojiParse.fromCodePoint(0x1f319)),
+ new EmojiBean(R.mipmap.emoji_0x2600, EmojiParse.fromChar((char) 0x2600)),
+ new EmojiBean(R.mipmap.emoji_0x2601, EmojiParse.fromChar((char) 0x2601)),
+ new EmojiBean(R.mipmap.emoji_0x26a1, EmojiParse.fromChar((char) 0x26a1)),
+ new EmojiBean(R.mipmap.emoji_0x2614, EmojiParse.fromChar((char) 0x2614)),
+ new EmojiBean(R.mipmap.emoji_0x1f47b, EmojiParse.fromCodePoint(0x1f47b)),
+ new EmojiBean(R.mipmap.emoji_0x1f385, EmojiParse.fromCodePoint(0x1f385)),
+ new EmojiBean(R.mipmap.emoji_0x1f381, EmojiParse.fromCodePoint(0x1f381)),
+ new EmojiBean(R.mipmap.emoji_0x1f4f1, EmojiParse.fromCodePoint(0x1f4f1)),
+ new EmojiBean(R.mipmap.emoji_0x1f50d, EmojiParse.fromCodePoint(0x1f50d)),
+ new EmojiBean(R.mipmap.emoji_0x1f4a3, EmojiParse.fromCodePoint(0x1f4a3)),
+ new EmojiBean(R.mipmap.emoji_0x26bd, EmojiParse.fromChar((char) 0x26bd)),
+ new EmojiBean(R.mipmap.emoji_0x2615, EmojiParse.fromChar((char) 0x2615)),
+ new EmojiBean(R.mipmap.emoji_0x1f37a, EmojiParse.fromCodePoint(0x1f37a)),
+ new EmojiBean(R.mipmap.emoji_0x1f382, EmojiParse.fromCodePoint(0x1f382)),
+ new EmojiBean(R.mipmap.emoji_0x1f3e0, EmojiParse.fromCodePoint(0x1f3e0)),
+ new EmojiBean(R.mipmap.emoji_0x1f697, EmojiParse.fromCodePoint(0x1f697)),
+ new EmojiBean(R.mipmap.emoji_0x1f559, EmojiParse.fromCodePoint(0x1f559))
+ };
+}
diff --git a/emoji/src/main/java/com/sj/emoji/EmojiBean.java b/emoji/src/main/java/com/sj/emoji/EmojiBean.java
new file mode 100644
index 00000000..4751521a
--- /dev/null
+++ b/emoji/src/main/java/com/sj/emoji/EmojiBean.java
@@ -0,0 +1,15 @@
+package com.sj.emoji;
+
+/**
+ * Created by sj on 16/3/22.
+ */
+public class EmojiBean {
+
+ public int icon;
+ public String emoji;
+
+ public EmojiBean(int icon, String emoji) {
+ this.icon = icon;
+ this.emoji = emoji;
+ }
+}
diff --git a/emoji/src/main/java/com/sj/emoji/EmojiDisplay.java b/emoji/src/main/java/com/sj/emoji/EmojiDisplay.java
new file mode 100644
index 00000000..f2488ee5
--- /dev/null
+++ b/emoji/src/main/java/com/sj/emoji/EmojiDisplay.java
@@ -0,0 +1,77 @@
+package com.sj.emoji;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.text.Spannable;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created by sj on 16/3/22.
+ */
+public class EmojiDisplay {
+
+ public static final int WRAP_DRAWABLE = -1;
+ public static final Pattern EMOJI_RANGE = Pattern.compile("[\\u20a0-\\u32ff\\ud83c\\udc00-\\ud83d\\udeff\\udbb9\\udce5-\\udbb9\\udcee]");
+
+ public static Matcher getMatcher(CharSequence matchStr) {
+ return EMOJI_RANGE.matcher(matchStr);
+ }
+
+ public static Spannable spannableFilter(Context context, Spannable spannable, CharSequence text, int fontSize) {
+ return spannableFilter(context, spannable, text, fontSize, null);
+ }
+
+ public static Spannable spannableFilter(Context context, Spannable spannable, CharSequence text, int fontSize, EmojiDisplayListener emojiDisplayListener) {
+ Matcher m = getMatcher(text);
+ if (m != null) {
+ while (m.find()) {
+ String emojiHex = Integer.toHexString(Character.codePointAt(m.group(), 0));
+ if (emojiDisplayListener == null) {
+ emojiDisplay(context, spannable, emojiHex, fontSize, m.start(), m.end());
+ } else {
+ emojiDisplayListener.onEmojiDisplay(context, spannable, emojiHex, fontSize, m.start(), m.end());
+ }
+ }
+ }
+ return spannable;
+ }
+
+ public static void emojiDisplay(Context context, Spannable spannable, String emojiHex, int fontSize, int start, int end) {
+ Drawable drawable = getDrawable(context, "emoji_0x" + emojiHex);
+ if (drawable != null) {
+ int itemHeight;
+ int itemWidth;
+ if (fontSize == WRAP_DRAWABLE) {
+ itemHeight = drawable.getIntrinsicHeight();
+ itemWidth = drawable.getIntrinsicWidth();
+ } else {
+ itemHeight = fontSize;
+ itemWidth = fontSize;
+ }
+
+ drawable.setBounds(0, 0, itemHeight, itemWidth);
+ EmojiSpan imageSpan = new EmojiSpan(drawable);
+ spannable.setSpan(imageSpan, start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+ }
+ }
+
+ public static Drawable getDrawable(Context context, String emojiName) {
+ int resID = context.getResources().getIdentifier(emojiName, "mipmap", context.getPackageName());
+ if (resID <= 0) {
+ resID = context.getResources().getIdentifier(emojiName, "drawable", context.getPackageName());
+ }
+ try {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ return context.getResources().getDrawable(resID, null);
+ } else {
+ return context.getResources().getDrawable(resID);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/emoji/src/main/java/com/sj/emoji/EmojiDisplayListener.java b/emoji/src/main/java/com/sj/emoji/EmojiDisplayListener.java
new file mode 100644
index 00000000..0a41a8e4
--- /dev/null
+++ b/emoji/src/main/java/com/sj/emoji/EmojiDisplayListener.java
@@ -0,0 +1,12 @@
+package com.sj.emoji;
+
+import android.content.Context;
+import android.text.Spannable;
+
+/**
+ * Created by sj on 16/3/22.
+ */
+public interface EmojiDisplayListener {
+
+ void onEmojiDisplay(Context context, Spannable spannable, String emojiHex, int fontSize, int start, int end);
+}
diff --git a/emoji/src/main/java/com/sj/emoji/EmojiParse.java b/emoji/src/main/java/com/sj/emoji/EmojiParse.java
new file mode 100644
index 00000000..0beb8922
--- /dev/null
+++ b/emoji/src/main/java/com/sj/emoji/EmojiParse.java
@@ -0,0 +1,19 @@
+package com.sj.emoji;
+
+/**
+ * Created by sj on 16/3/22.
+ */
+public class EmojiParse {
+
+ public static String fromChar(char ch) { return Character.toString(ch); }
+
+ public static String fromCodePoint(int codePoint) { return newString(codePoint); }
+
+ public static final String newString(int codePoint) {
+ if (Character.charCount(codePoint) == 1) {
+ return String.valueOf(codePoint);
+ } else {
+ return new String(Character.toChars(codePoint));
+ }
+ }
+}
\ No newline at end of file
diff --git a/emoji/src/main/java/com/sj/emoji/EmojiSpan.java b/emoji/src/main/java/com/sj/emoji/EmojiSpan.java
new file mode 100644
index 00000000..b0ba32c5
--- /dev/null
+++ b/emoji/src/main/java/com/sj/emoji/EmojiSpan.java
@@ -0,0 +1,52 @@
+package com.sj.emoji;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.text.style.ImageSpan;
+
+/**
+ * Created by sj on 16/3/22.
+ */
+public class EmojiSpan extends ImageSpan {
+
+ public EmojiSpan(Drawable drawable) {
+ super(drawable);
+ }
+
+ public EmojiSpan(Context context, int resourceId) {
+ super(context, resourceId);
+ }
+
+ public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fontMetricsInt) {
+ Drawable drawable = getDrawable();
+ Rect rect = drawable.getBounds();
+ if (fontMetricsInt != null) {
+ Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
+ int fontHeight = fmPaint.bottom - fmPaint.top;
+ int drHeight = rect.bottom - rect.top;
+
+ int top = drHeight / 2 - fontHeight / 4;
+ int bottom = drHeight / 2 + fontHeight / 4;
+
+ fontMetricsInt.ascent = -bottom;
+ fontMetricsInt.top = -bottom;
+ fontMetricsInt.bottom = top;
+ fontMetricsInt.descent = top;
+ }
+ return rect.right;
+ }
+
+ @Override
+ public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
+ Drawable drawable = getDrawable();
+ canvas.save();
+ int transY = ((bottom - top) - drawable.getBounds().bottom) / 2 + top;
+ canvas.translate(x, transY);
+ drawable.draw(canvas);
+ canvas.restore();
+ }
+}
+
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f319.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f319.png
new file mode 100644
index 00000000..2a410759
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f319.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f31f.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f31f.png
new file mode 100644
index 00000000..a7a292ef
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f31f.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f339.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f339.png
new file mode 100644
index 00000000..ceed9857
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f339.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f33b.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f33b.png
new file mode 100644
index 00000000..9dc791f2
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f33b.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f341.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f341.png
new file mode 100644
index 00000000..b5e26df2
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f341.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f343.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f343.png
new file mode 100644
index 00000000..e63dc326
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f343.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f37a.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f37a.png
new file mode 100644
index 00000000..435d79d6
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f37a.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f380.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f380.png
new file mode 100644
index 00000000..dede51a2
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f380.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f381.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f381.png
new file mode 100644
index 00000000..8817e1fd
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f381.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f382.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f382.png
new file mode 100644
index 00000000..40bd3d0a
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f382.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f385.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f385.png
new file mode 100644
index 00000000..bcdff749
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f385.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f3e0.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f3e0.png
new file mode 100644
index 00000000..fdcfc193
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f3e0.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f431.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f431.png
new file mode 100644
index 00000000..5e4d1a1e
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f431.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f436.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f436.png
new file mode 100644
index 00000000..faef9288
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f436.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f444.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f444.png
new file mode 100644
index 00000000..549e9a04
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f444.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f446.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f446.png
new file mode 100644
index 00000000..e11e0b3f
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f446.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f447.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f447.png
new file mode 100644
index 00000000..4c190389
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f447.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f448.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f448.png
new file mode 100644
index 00000000..68f105b3
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f448.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f449.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f449.png
new file mode 100644
index 00000000..b61e3779
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f449.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44a.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44a.png
new file mode 100644
index 00000000..524f278c
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44a.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44c.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44c.png
new file mode 100644
index 00000000..f261d93e
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44c.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44d.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44d.png
new file mode 100644
index 00000000..4125c73e
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44d.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44e.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44e.png
new file mode 100644
index 00000000..66d1f114
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44e.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44f.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44f.png
new file mode 100644
index 00000000..08b2c6f0
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f44f.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f457.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f457.png
new file mode 100644
index 00000000..b30cf856
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f457.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f466.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f466.png
new file mode 100644
index 00000000..14ea3642
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f466.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f467.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f467.png
new file mode 100644
index 00000000..c8393fd8
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f467.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f468.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f468.png
new file mode 100644
index 00000000..f73a1aa7
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f468.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f469.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f469.png
new file mode 100644
index 00000000..30108b47
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f469.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f47b.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f47b.png
new file mode 100644
index 00000000..334b1c78
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f47b.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f47f.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f47f.png
new file mode 100644
index 00000000..e476bf8d
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f47f.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f48e.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f48e.png
new file mode 100644
index 00000000..fd92d147
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f48e.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f494.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f494.png
new file mode 100644
index 00000000..2af56a43
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f494.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f4a3.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f4a3.png
new file mode 100644
index 00000000..d2872b49
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f4a3.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f4aa.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f4aa.png
new file mode 100644
index 00000000..058fc609
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f4aa.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f4f1.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f4f1.png
new file mode 100644
index 00000000..17724561
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f4f1.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f50d.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f50d.png
new file mode 100644
index 00000000..3c924d1b
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f50d.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f559.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f559.png
new file mode 100644
index 00000000..2ac3e345
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f559.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f601.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f601.png
new file mode 100644
index 00000000..2b0d088c
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f601.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f602.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f602.png
new file mode 100644
index 00000000..055edf43
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f602.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f603.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f603.png
new file mode 100644
index 00000000..23a3cf5e
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f603.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f604.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f604.png
new file mode 100644
index 00000000..cbdc8a7a
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f604.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f609.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f609.png
new file mode 100644
index 00000000..38a261c1
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f609.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60a.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60a.png
new file mode 100644
index 00000000..205c51f5
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60a.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60c.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60c.png
new file mode 100644
index 00000000..9d6b68f6
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60c.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60d.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60d.png
new file mode 100644
index 00000000..a2023304
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60d.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60f.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60f.png
new file mode 100644
index 00000000..1f8682d4
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f60f.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f612.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f612.png
new file mode 100644
index 00000000..eacaf9ed
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f612.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f613.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f613.png
new file mode 100644
index 00000000..9c127fe0
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f613.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f614.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f614.png
new file mode 100644
index 00000000..032e0f7e
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f614.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f616.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f616.png
new file mode 100644
index 00000000..7d27a941
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f616.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f618.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f618.png
new file mode 100644
index 00000000..93ba6e48
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f618.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61a.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61a.png
new file mode 100644
index 00000000..1a6b76df
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61a.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61c.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61c.png
new file mode 100644
index 00000000..5438397b
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61c.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61d.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61d.png
new file mode 100644
index 00000000..fc83106c
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61d.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61e.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61e.png
new file mode 100644
index 00000000..92f8263e
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f61e.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f620.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f620.png
new file mode 100644
index 00000000..4641fe65
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f620.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f621.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f621.png
new file mode 100644
index 00000000..c4abd75b
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f621.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f622.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f622.png
new file mode 100644
index 00000000..f3b793d1
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f622.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f623.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f623.png
new file mode 100644
index 00000000..640e933f
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f623.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f625.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f625.png
new file mode 100644
index 00000000..74411f49
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f625.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f628.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f628.png
new file mode 100644
index 00000000..3a88f78a
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f628.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f62a.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f62a.png
new file mode 100644
index 00000000..541dc20c
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f62a.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f62d.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f62d.png
new file mode 100644
index 00000000..68d48a80
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f62d.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f630.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f630.png
new file mode 100644
index 00000000..12ea763a
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f630.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f631.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f631.png
new file mode 100644
index 00000000..b9d6e67c
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f631.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f632.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f632.png
new file mode 100644
index 00000000..8c96879d
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f632.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f633.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f633.png
new file mode 100644
index 00000000..9fbf8ece
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f633.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f637.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f637.png
new file mode 100644
index 00000000..6e08fd16
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f637.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f64f.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f64f.png
new file mode 100644
index 00000000..be22349a
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f64f.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f697.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f697.png
new file mode 100644
index 00000000..bd7fcf69
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x1f697.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x2600.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x2600.png
new file mode 100644
index 00000000..ef778f33
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x2600.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x2601.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x2601.png
new file mode 100644
index 00000000..c61d3622
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x2601.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x2614.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x2614.png
new file mode 100644
index 00000000..6a8f742c
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x2614.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x2615.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x2615.png
new file mode 100644
index 00000000..798ee53d
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x2615.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x26a1.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x26a1.png
new file mode 100644
index 00000000..24df5263
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x26a1.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x26bd.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x26bd.png
new file mode 100644
index 00000000..f09be611
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x26bd.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x270a.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x270a.png
new file mode 100644
index 00000000..b35144c1
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x270a.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x270c.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x270c.png
new file mode 100644
index 00000000..af3d2502
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x270c.png differ
diff --git a/emoji/src/main/res/mipmap-xhdpi/emoji_0x2764.png b/emoji/src/main/res/mipmap-xhdpi/emoji_0x2764.png
new file mode 100644
index 00000000..2176cbc7
Binary files /dev/null and b/emoji/src/main/res/mipmap-xhdpi/emoji_0x2764.png differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index fa48f216..2ece8d27 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Thu Jun 08 10:57:37 CST 2017
+#Thu Oct 26 21:36:10 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
diff --git a/reclib-qq/build.gradle b/reclib-qq/build.gradle
index 0cd65103..c3e63957 100644
--- a/reclib-qq/build.gradle
+++ b/reclib-qq/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 23
- buildToolsVersion '25.0.0'
+ buildToolsVersion '28.0.3'
defaultConfig {
minSdkVersion 9
@@ -19,5 +19,5 @@ android {
}
dependencies {
- compile 'com.android.support:appcompat-v7:23.2.1'
+ implementation 'com.android.support:appcompat-v7:23.2.1'
}
diff --git a/reclib-qq/src/main/AndroidManifest.xml b/reclib-qq/src/main/AndroidManifest.xml
index 8fdf6af3..16bc1a60 100644
--- a/reclib-qq/src/main/AndroidManifest.xml
+++ b/reclib-qq/src/main/AndroidManifest.xml
@@ -2,7 +2,6 @@
package="sj.qqkeyboard">
diff --git a/reclib-testemoticons/build.gradle b/reclib-testemoticons/build.gradle
index e668a116..a5558cb8 100644
--- a/reclib-testemoticons/build.gradle
+++ b/reclib-testemoticons/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 23
- buildToolsVersion '25.0.0'
+ buildToolsVersion '28.0.3'
defaultConfig {
minSdkVersion 9
diff --git a/settings.gradle b/settings.gradle
index 9f6b9b67..448db47d 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':chatapp',':reclib-qq', ':reclib-testemoticons'
+include ':chatapp',':reclib-qq', ':reclib-testemoticons', ':emoji'