├── .gitignore ├── README.md ├── app ├── .gitignore ├── EasyIM-release.apk ├── build.gradle ├── libs │ ├── android-viewbadger.jar │ ├── armeabi-v7a │ │ └── libjpush173.so │ ├── armeabi │ │ └── libjpush173.so │ └── jpush-sdk-release1.7.3.jar ├── manifest-merger-release-report.txt ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── me │ │ └── xiezefan │ │ └── easyim │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java-gen │ └── me │ │ └── xiezefan │ │ └── easyim │ │ └── dao │ │ ├── ChatItem.java │ │ ├── ChatItemDao.java │ │ ├── ChatSession.java │ │ ├── ChatSessionDao.java │ │ ├── DaoMaster.java │ │ ├── DaoSession.java │ │ ├── Friend.java │ │ ├── FriendDao.java │ │ ├── FriendRequest.java │ │ └── FriendRequestDao.java │ ├── java │ └── me │ │ └── xiezefan │ │ └── easyim │ │ ├── Application.java │ │ ├── common │ │ ├── ConstantHelper.java │ │ ├── DataCleanHelper.java │ │ ├── FriendHelper.java │ │ ├── JPushReceiver.java │ │ ├── PromptHelper.java │ │ └── SPHelper.java │ │ ├── event │ │ ├── NotificationEventManager.java │ │ └── model │ │ │ ├── BackPressedEvent.java │ │ │ ├── ChatMessageEvent.java │ │ │ ├── FriendRequestEvent.java │ │ │ ├── NewFriendEvent.java │ │ │ └── ProcessEvent.java │ │ ├── model │ │ ├── FriendRequestStatus.java │ │ ├── MessageStatus.java │ │ └── MessageType.java │ │ ├── module │ │ ├── AndroidModule.java │ │ ├── DaoModule.java │ │ ├── ForApplication.java │ │ └── RequestModule.java │ │ ├── mvp │ │ ├── activity │ │ │ ├── BaseActivity.java │ │ │ ├── DispatchActivity.java │ │ │ ├── FriendAddActivity.java │ │ │ ├── FriendsSquareActivity.java │ │ │ ├── LoginActivity.java │ │ │ ├── RegisterActivity.java │ │ │ ├── SearchActivity.java │ │ │ ├── SearchResultActivity.java │ │ │ └── TestActivity.java │ │ ├── adapter │ │ │ ├── FriendSquareAdapter.java │ │ │ ├── LeftMenuAdapter.java │ │ │ └── SearchResultAdapter.java │ │ ├── base │ │ │ ├── BaseView.java │ │ │ ├── SimpleRequestListener.java │ │ │ └── UserInteractor.java │ │ ├── chat │ │ │ ├── ChatActivity.java │ │ │ ├── ChatAdapter.java │ │ │ ├── ChatInteractor.java │ │ │ ├── ChatPresenter.java │ │ │ ├── ChatPresenterListener.java │ │ │ └── ChatView.java │ │ ├── chat_session │ │ │ ├── ChatSessionAdapter.java │ │ │ ├── ChatSessionFragment.java │ │ │ ├── ChatSessionInteractor.java │ │ │ ├── ChatSessionPresenter.java │ │ │ └── ChatSessionView.java │ │ ├── common │ │ │ ├── FileUploadInteractor.java │ │ │ └── RoundedTransformation.java │ │ ├── contact │ │ │ ├── ContactAdapter.java │ │ │ ├── ContactFragment.java │ │ │ ├── ContactPresenter.java │ │ │ └── ContactView.java │ │ ├── friend_home │ │ │ ├── FriendHomeActivity.java │ │ │ ├── FriendHomePresenter.java │ │ │ └── FriendHomeView.java │ │ ├── gallery │ │ │ ├── GalleryActivity.java │ │ │ ├── GalleryAdapter.java │ │ │ ├── GalleryInteractor.java │ │ │ ├── GalleryPresenter.java │ │ │ └── GalleryView.java │ │ ├── interactor │ │ │ └── FriendInteractor.java │ │ ├── main │ │ │ ├── #MainActivity.java# │ │ │ ├── MainActivity.java │ │ │ ├── MainInteractor.java │ │ │ ├── MainPresenter.java │ │ │ └── MainView.java │ │ ├── new_friend │ │ │ ├── #NewFriendFragment.java# │ │ │ ├── FriendAddCallback.java │ │ │ ├── NewFriendAdapter.java │ │ │ ├── NewFriendFragment.java │ │ │ ├── NewFriendInteractor.java │ │ │ ├── NewFriendPresenter.java │ │ │ └── NewFriendView.java │ │ └── user_info │ │ │ ├── UserInfoAdapter.java │ │ │ ├── UserInfoFragment.java │ │ │ ├── UserInfoInteractor.java │ │ │ ├── UserInfoPresenter.java │ │ │ └── UserInfoView.java │ │ ├── net │ │ ├── AuthorizationRequestInterceptor.java │ │ ├── DefaultErrorHandler.java │ │ ├── FriendshipResource.java │ │ ├── MessageResource.java │ │ ├── RequestManager.java │ │ ├── UploadTokenResource.java │ │ ├── UserResource.java │ │ ├── from │ │ │ ├── FriendshipAddForm.java │ │ │ ├── LoginForm.java │ │ │ ├── MessageSendForm.java │ │ │ ├── MessageStatusUpdateForm.java │ │ │ ├── RegisterForm.java │ │ │ └── UserUpdateForm.java │ │ └── vo │ │ │ ├── DefaultResponseVo.java │ │ │ ├── MessageVo.java │ │ │ ├── RequestFailError.java │ │ │ ├── UploadTokenVo.java │ │ │ └── UserVo.java │ │ ├── service │ │ ├── FriendshipService.java │ │ ├── MessageService.java │ │ └── UserService.java │ │ ├── util │ │ ├── BitmapUtil.java │ │ ├── CollectionUtil.java │ │ ├── CommonUtil.java │ │ ├── DateUtil.java │ │ ├── DisplayUtil.java │ │ ├── JsonUtil.java │ │ └── StringUtil.java │ │ └── widget │ │ └── ResizeRecyclerView.java │ └── res │ ├── anim │ └── default_rotating.xml │ ├── drawable-hdpi │ ├── ic_action_back.png │ ├── ic_action_cancel.png │ ├── ic_action_search.png │ ├── ic_action_storage.png │ └── ic_launcher.png │ ├── drawable-mdpi │ ├── ic_action_back.png │ ├── ic_action_cancel.png │ ├── ic_action_search.png │ ├── ic_action_storage.png │ └── ic_launcher.png │ ├── drawable-v21 │ └── bg_default_item.xml │ ├── drawable-xhdpi │ ├── bg_chat_item_left.9.png │ ├── bg_chat_item_right.9.png │ ├── bg_edit_text.9.png │ ├── default_user_profile.png │ ├── ic_action_back.png │ ├── ic_action_cancel.png │ ├── ic_action_search.png │ ├── ic_action_storage.png │ ├── ic_camera.png │ ├── ic_launcher.png │ └── ic_loading.png │ ├── drawable-xxhdpi │ ├── ic_action_back.png │ ├── ic_action_cancel.png │ ├── ic_action_search.png │ ├── ic_action_storage.png │ └── ic_launcher.png │ ├── drawable │ ├── bg_chat_notification.xml │ ├── bg_default_gallery.xml │ ├── bg_default_item.xml │ ├── bg_friend_add_btn.xml │ ├── bg_left_menu_icon.xml │ ├── bg_login_btn.xml │ ├── bg_register_btn.xml │ ├── bg_send_btn.xml │ ├── bg_warming_btn.xml │ └── temp_image.png │ ├── layout │ ├── activity_chat.xml │ ├── activity_contact.xml │ ├── activity_friend_add.xml │ ├── activity_friend_home.xml │ ├── activity_friend_square.xml │ ├── activity_gallery.xml │ ├── activity_login.xml │ ├── activity_main.xml │ ├── activity_register.xml │ ├── activity_search.xml │ ├── activity_search_result.xml │ ├── activity_test.xml │ ├── dialog_friend_request.xml │ ├── fragment_chat_session.xml │ ├── fragment_contact.xml │ ├── fragment_list.xml │ ├── item_chat_image_left.xml │ ├── item_chat_image_right.xml │ ├── item_chat_left.xml │ ├── item_chat_notification.xml │ ├── item_chat_right.xml │ ├── item_chat_session.xml │ ├── item_contact.xml │ ├── item_friend_header.xml │ ├── item_friend_message.xml │ ├── item_friend_search.xml │ ├── item_friend_search_result.xml │ ├── item_friend_title.xml │ ├── item_gallery.xml │ ├── item_left_menu.xml │ ├── item_left_menu_divider.xml │ ├── item_left_menu_divider2.xml │ ├── item_loading.xml │ ├── item_text.xml │ ├── item_user_info_button.xml │ ├── item_user_info_divider.xml │ ├── item_user_info_header.xml │ ├── item_user_info_image.xml │ ├── item_user_info_text.xml │ ├── view_toolbar_main.xml │ ├── view_toolbar_main_no_elevation.xml │ └── view_toolbar_search.xml │ ├── menu │ └── menu_main.xml │ ├── raw │ └── ping_8.wav │ ├── values-w820dp │ └── dimens.xml │ ├── values │ ├── color.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ └── searchable.xml ├── build.gradle ├── gradle.properties ├── gradle ├── local.properties └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── greendaogenerator ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── me │ └── xiezefna │ └── dao │ └── generator │ └── GreenDaoGenerator.java ├── keystorm.jks └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | 8 | .idea 9 | *.iml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EasyIM-Android 2 | 3 | EasyIM是一个移动即时通讯应用。是我的本科毕业设计。 4 | 5 | 因为实习占用了大四的大部分时间,导致EasyIM只完成了部分功能便参与答辩。虽然最终侥幸过了毕设答辩,但效果与自己期望的相去甚远。 6 | 7 | 开始工作后,有比较多的空闲时间,我打算慢慢完善该项目,并将近期所学习的一些新技术应用到该项目中。 8 | 9 | 10 | ## 简述 11 | 12 | 该项目分为两部分: 13 | 14 | * [EasyIM-Server][1] : EasyIM服务端 15 | * [EasyIM-Android][2] : EasyIM Android端 16 | 17 | EasyIM-Server主要完成一下功能: 18 | 19 | * 用户基础功能 20 | * 好友功能 21 | * 点对点的消息发送功能 22 | * 离线消息功能 23 | 24 | ### 技术与框架 25 | 26 | * ButterKnife 27 | * Picasso 28 | * Retrofit 29 | * GreenDao 30 | * EventBus 31 | * RxAndroid 32 | 33 | PS:项目中使用了Lambda表达式,所以,请确保安装了JDK1.8及Gradle2.2以上。 34 | 35 | ## 效果图 36 | 37 | ![3] 38 | 39 | [1]:https://github.com/xiezefan/EasyIM-Server 40 | [2]:https://github.com/xiezefan/EasyIM-Android 41 | [3]:http://7jpp6b.com1.z0.glb.clouddn.com/blog/easyim_all.jpg 42 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/EasyIM-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/EasyIM-release.apk -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "me.tatarka.retrolambda" version "3.0.1" 3 | } 4 | apply plugin: 'com.android.application' 5 | 6 | 7 | android { 8 | compileSdkVersion 21 9 | buildToolsVersion "21.1.2" 10 | 11 | defaultConfig { 12 | applicationId "me.xiezefan.easyim" 13 | minSdkVersion 15 14 | targetSdkVersion 21 15 | versionCode 1 16 | versionName "1.0" 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | 25 | sourceSets.main { 26 | jniLibs.srcDirs = ['libs'] // <-- Set your folder here! 27 | manifest.srcFile 'src/main/AndroidManifest.xml' 28 | java.srcDirs = ['src/main/java', 'src/main/java-gen'] 29 | res.srcDirs = ['src/main/res'] 30 | } 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | } 38 | 39 | dependencies { 40 | compile fileTree(dir: 'libs', include: ['*.jar']) 41 | compile "com.android.support:appcompat-v7:21.0.0" 42 | compile 'com.android.support:support-v13:21.+' 43 | compile 'com.android.support:support-v4:21.+' 44 | compile 'com.android.support:palette-v7:+' 45 | compile 'com.android.support:recyclerview-v7:+' 46 | compile 'com.android.support:cardview-v7:21.0.+' 47 | compile 'com.jakewharton:butterknife:5.1.2' 48 | compile 'com.jakewharton.timber:timber:2.5.0' 49 | compile 'com.facebook.rebound:rebound:0.3.6' 50 | compile 'com.squareup.picasso:picasso:2.5.0' 51 | compile 'com.afollestad:material-dialogs:0.7.3.1' 52 | compile 'com.squareup.retrofit:retrofit:1.9.0' 53 | compile 'de.greenrobot:greendao:1.3.7' 54 | compile 'com.orhanobut:logger:1.4' 55 | compile 'de.greenrobot:eventbus:2.4.0' 56 | compile 'io.reactivex:rxandroid:0.24.0' 57 | compile 'com.qiniu:qiniu-android-sdk:7.0.4' 58 | 59 | 60 | 61 | compile 'com.squareup.dagger:dagger:1.2.2' 62 | provided 'com.squareup.dagger:dagger-compiler:1.2.2' 63 | 64 | 65 | } 66 | -------------------------------------------------------------------------------- /app/libs/android-viewbadger.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/libs/android-viewbadger.jar -------------------------------------------------------------------------------- /app/libs/armeabi-v7a/libjpush173.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/libs/armeabi-v7a/libjpush173.so -------------------------------------------------------------------------------- /app/libs/armeabi/libjpush173.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/libs/armeabi/libjpush173.so -------------------------------------------------------------------------------- /app/libs/jpush-sdk-release1.7.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/libs/jpush-sdk-release1.7.3.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\xiezefan-pc\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/me/xiezefan/easyim/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/java-gen/me/xiezefan/easyim/dao/ChatItem.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.dao; 2 | 3 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit. 4 | /** 5 | * Entity mapped to table CHAT_ITEM. 6 | */ 7 | public class ChatItem { 8 | 9 | private Long id; 10 | private String msgId; 11 | private Long chatSessionId; 12 | private String targetId; 13 | private String type; 14 | private String fromId; 15 | private String content; 16 | private String extras; 17 | private String status; 18 | private Boolean isSelf; 19 | private Long createTime; 20 | 21 | public ChatItem() { 22 | } 23 | 24 | public ChatItem(Long id) { 25 | this.id = id; 26 | } 27 | 28 | public ChatItem(Long id, String msgId, Long chatSessionId, String targetId, String type, String fromId, String content, String extras, String status, Boolean isSelf, Long createTime) { 29 | this.id = id; 30 | this.msgId = msgId; 31 | this.chatSessionId = chatSessionId; 32 | this.targetId = targetId; 33 | this.type = type; 34 | this.fromId = fromId; 35 | this.content = content; 36 | this.extras = extras; 37 | this.status = status; 38 | this.isSelf = isSelf; 39 | this.createTime = createTime; 40 | } 41 | 42 | public Long getId() { 43 | return id; 44 | } 45 | 46 | public void setId(Long id) { 47 | this.id = id; 48 | } 49 | 50 | public String getMsgId() { 51 | return msgId; 52 | } 53 | 54 | public void setMsgId(String msgId) { 55 | this.msgId = msgId; 56 | } 57 | 58 | public Long getChatSessionId() { 59 | return chatSessionId; 60 | } 61 | 62 | public void setChatSessionId(Long chatSessionId) { 63 | this.chatSessionId = chatSessionId; 64 | } 65 | 66 | public String getTargetId() { 67 | return targetId; 68 | } 69 | 70 | public void setTargetId(String targetId) { 71 | this.targetId = targetId; 72 | } 73 | 74 | public String getType() { 75 | return type; 76 | } 77 | 78 | public void setType(String type) { 79 | this.type = type; 80 | } 81 | 82 | public String getFromId() { 83 | return fromId; 84 | } 85 | 86 | public void setFromId(String fromId) { 87 | this.fromId = fromId; 88 | } 89 | 90 | public String getContent() { 91 | return content; 92 | } 93 | 94 | public void setContent(String content) { 95 | this.content = content; 96 | } 97 | 98 | public String getExtras() { 99 | return extras; 100 | } 101 | 102 | public void setExtras(String extras) { 103 | this.extras = extras; 104 | } 105 | 106 | public String getStatus() { 107 | return status; 108 | } 109 | 110 | public void setStatus(String status) { 111 | this.status = status; 112 | } 113 | 114 | public Boolean getIsSelf() { 115 | return isSelf; 116 | } 117 | 118 | public void setIsSelf(Boolean isSelf) { 119 | this.isSelf = isSelf; 120 | } 121 | 122 | public Long getCreateTime() { 123 | return createTime; 124 | } 125 | 126 | public void setCreateTime(Long createTime) { 127 | this.createTime = createTime; 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /app/src/main/java-gen/me/xiezefan/easyim/dao/ChatSession.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.dao; 2 | 3 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit. 4 | /** 5 | * Entity mapped to table CHAT_SESSION. 6 | */ 7 | public class ChatSession { 8 | 9 | private Long id; 10 | private String title; 11 | private String lastMessage; 12 | private String avatar; 13 | private Integer unread; 14 | private Long lastTime; 15 | private String targetId; 16 | 17 | public ChatSession() { 18 | } 19 | 20 | public ChatSession(Long id) { 21 | this.id = id; 22 | } 23 | 24 | public ChatSession(Long id, String title, String lastMessage, String avatar, Integer unread, Long lastTime, String targetId) { 25 | this.id = id; 26 | this.title = title; 27 | this.lastMessage = lastMessage; 28 | this.avatar = avatar; 29 | this.unread = unread; 30 | this.lastTime = lastTime; 31 | this.targetId = targetId; 32 | } 33 | 34 | public Long getId() { 35 | return id; 36 | } 37 | 38 | public void setId(Long id) { 39 | this.id = id; 40 | } 41 | 42 | public String getTitle() { 43 | return title; 44 | } 45 | 46 | public void setTitle(String title) { 47 | this.title = title; 48 | } 49 | 50 | public String getLastMessage() { 51 | return lastMessage; 52 | } 53 | 54 | public void setLastMessage(String lastMessage) { 55 | this.lastMessage = lastMessage; 56 | } 57 | 58 | public String getAvatar() { 59 | return avatar; 60 | } 61 | 62 | public void setAvatar(String avatar) { 63 | this.avatar = avatar; 64 | } 65 | 66 | public Integer getUnread() { 67 | return unread; 68 | } 69 | 70 | public void setUnread(Integer unread) { 71 | this.unread = unread; 72 | } 73 | 74 | public Long getLastTime() { 75 | return lastTime; 76 | } 77 | 78 | public void setLastTime(Long lastTime) { 79 | this.lastTime = lastTime; 80 | } 81 | 82 | public String getTargetId() { 83 | return targetId; 84 | } 85 | 86 | public void setTargetId(String targetId) { 87 | this.targetId = targetId; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /app/src/main/java-gen/me/xiezefan/easyim/dao/DaoMaster.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.dao; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteDatabase.CursorFactory; 6 | import android.database.sqlite.SQLiteOpenHelper; 7 | import android.util.Log; 8 | import de.greenrobot.dao.AbstractDaoMaster; 9 | import de.greenrobot.dao.identityscope.IdentityScopeType; 10 | 11 | import me.xiezefan.easyim.dao.FriendDao; 12 | import me.xiezefan.easyim.dao.FriendRequestDao; 13 | import me.xiezefan.easyim.dao.ChatSessionDao; 14 | import me.xiezefan.easyim.dao.ChatItemDao; 15 | 16 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. 17 | /** 18 | * Master of DAO (schema version 1): knows all DAOs. 19 | */ 20 | public class DaoMaster extends AbstractDaoMaster { 21 | public static final int SCHEMA_VERSION = 1; 22 | 23 | /** Creates underlying database table using DAOs. */ 24 | public static void createAllTables(SQLiteDatabase db, boolean ifNotExists) { 25 | FriendDao.createTable(db, ifNotExists); 26 | FriendRequestDao.createTable(db, ifNotExists); 27 | ChatSessionDao.createTable(db, ifNotExists); 28 | ChatItemDao.createTable(db, ifNotExists); 29 | } 30 | 31 | /** Drops underlying database table using DAOs. */ 32 | public static void dropAllTables(SQLiteDatabase db, boolean ifExists) { 33 | FriendDao.dropTable(db, ifExists); 34 | FriendRequestDao.dropTable(db, ifExists); 35 | ChatSessionDao.dropTable(db, ifExists); 36 | ChatItemDao.dropTable(db, ifExists); 37 | } 38 | 39 | public static abstract class OpenHelper extends SQLiteOpenHelper { 40 | 41 | public OpenHelper(Context context, String name, CursorFactory factory) { 42 | super(context, name, factory, SCHEMA_VERSION); 43 | } 44 | 45 | @Override 46 | public void onCreate(SQLiteDatabase db) { 47 | Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION); 48 | createAllTables(db, false); 49 | } 50 | } 51 | 52 | /** WARNING: Drops all table on Upgrade! Use only during development. */ 53 | public static class DevOpenHelper extends OpenHelper { 54 | public DevOpenHelper(Context context, String name, CursorFactory factory) { 55 | super(context, name, factory); 56 | } 57 | 58 | @Override 59 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 60 | Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables"); 61 | dropAllTables(db, true); 62 | onCreate(db); 63 | } 64 | } 65 | 66 | public DaoMaster(SQLiteDatabase db) { 67 | super(db, SCHEMA_VERSION); 68 | registerDaoClass(FriendDao.class); 69 | registerDaoClass(FriendRequestDao.class); 70 | registerDaoClass(ChatSessionDao.class); 71 | registerDaoClass(ChatItemDao.class); 72 | } 73 | 74 | public DaoSession newSession() { 75 | return new DaoSession(db, IdentityScopeType.Session, daoConfigMap); 76 | } 77 | 78 | public DaoSession newSession(IdentityScopeType type) { 79 | return new DaoSession(db, type, daoConfigMap); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java-gen/me/xiezefan/easyim/dao/DaoSession.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.dao; 2 | 3 | import android.database.sqlite.SQLiteDatabase; 4 | 5 | import java.util.Map; 6 | 7 | import de.greenrobot.dao.AbstractDao; 8 | import de.greenrobot.dao.AbstractDaoSession; 9 | import de.greenrobot.dao.identityscope.IdentityScopeType; 10 | import de.greenrobot.dao.internal.DaoConfig; 11 | 12 | import me.xiezefan.easyim.dao.Friend; 13 | import me.xiezefan.easyim.dao.FriendRequest; 14 | import me.xiezefan.easyim.dao.ChatSession; 15 | import me.xiezefan.easyim.dao.ChatItem; 16 | 17 | import me.xiezefan.easyim.dao.FriendDao; 18 | import me.xiezefan.easyim.dao.FriendRequestDao; 19 | import me.xiezefan.easyim.dao.ChatSessionDao; 20 | import me.xiezefan.easyim.dao.ChatItemDao; 21 | 22 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. 23 | 24 | /** 25 | * {@inheritDoc} 26 | * 27 | * @see de.greenrobot.dao.AbstractDaoSession 28 | */ 29 | public class DaoSession extends AbstractDaoSession { 30 | 31 | private final DaoConfig friendDaoConfig; 32 | private final DaoConfig friendRequestDaoConfig; 33 | private final DaoConfig chatSessionDaoConfig; 34 | private final DaoConfig chatItemDaoConfig; 35 | 36 | private final FriendDao friendDao; 37 | private final FriendRequestDao friendRequestDao; 38 | private final ChatSessionDao chatSessionDao; 39 | private final ChatItemDao chatItemDao; 40 | 41 | public DaoSession(SQLiteDatabase db, IdentityScopeType type, Map>, DaoConfig> 42 | daoConfigMap) { 43 | super(db); 44 | 45 | friendDaoConfig = daoConfigMap.get(FriendDao.class).clone(); 46 | friendDaoConfig.initIdentityScope(type); 47 | 48 | friendRequestDaoConfig = daoConfigMap.get(FriendRequestDao.class).clone(); 49 | friendRequestDaoConfig.initIdentityScope(type); 50 | 51 | chatSessionDaoConfig = daoConfigMap.get(ChatSessionDao.class).clone(); 52 | chatSessionDaoConfig.initIdentityScope(type); 53 | 54 | chatItemDaoConfig = daoConfigMap.get(ChatItemDao.class).clone(); 55 | chatItemDaoConfig.initIdentityScope(type); 56 | 57 | friendDao = new FriendDao(friendDaoConfig, this); 58 | friendRequestDao = new FriendRequestDao(friendRequestDaoConfig, this); 59 | chatSessionDao = new ChatSessionDao(chatSessionDaoConfig, this); 60 | chatItemDao = new ChatItemDao(chatItemDaoConfig, this); 61 | 62 | registerDao(Friend.class, friendDao); 63 | registerDao(FriendRequest.class, friendRequestDao); 64 | registerDao(ChatSession.class, chatSessionDao); 65 | registerDao(ChatItem.class, chatItemDao); 66 | } 67 | 68 | public void clear() { 69 | friendDaoConfig.getIdentityScope().clear(); 70 | friendRequestDaoConfig.getIdentityScope().clear(); 71 | chatSessionDaoConfig.getIdentityScope().clear(); 72 | chatItemDaoConfig.getIdentityScope().clear(); 73 | } 74 | 75 | public FriendDao getFriendDao() { 76 | return friendDao; 77 | } 78 | 79 | public FriendRequestDao getFriendRequestDao() { 80 | return friendRequestDao; 81 | } 82 | 83 | public ChatSessionDao getChatSessionDao() { 84 | return chatSessionDao; 85 | } 86 | 87 | public ChatItemDao getChatItemDao() { 88 | return chatItemDao; 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java-gen/me/xiezefan/easyim/dao/Friend.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.dao; 2 | 3 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit. 4 | /** 5 | * Entity mapped to table FRIEND. 6 | */ 7 | public class Friend { 8 | 9 | private Long id; 10 | private String uid; 11 | private String username; 12 | private String nickname; 13 | private String avatar; 14 | private String description; 15 | private String sex; 16 | private String location; 17 | 18 | public Friend() { 19 | } 20 | 21 | public Friend(Long id) { 22 | this.id = id; 23 | } 24 | 25 | public Friend(Long id, String uid, String username, String nickname, String avatar, String description, String sex, String location) { 26 | this.id = id; 27 | this.uid = uid; 28 | this.username = username; 29 | this.nickname = nickname; 30 | this.avatar = avatar; 31 | this.description = description; 32 | this.sex = sex; 33 | this.location = location; 34 | } 35 | 36 | public Long getId() { 37 | return id; 38 | } 39 | 40 | public void setId(Long id) { 41 | this.id = id; 42 | } 43 | 44 | public String getUid() { 45 | return uid; 46 | } 47 | 48 | public void setUid(String uid) { 49 | this.uid = uid; 50 | } 51 | 52 | public String getUsername() { 53 | return username; 54 | } 55 | 56 | public void setUsername(String username) { 57 | this.username = username; 58 | } 59 | 60 | public String getNickname() { 61 | return nickname; 62 | } 63 | 64 | public void setNickname(String nickname) { 65 | this.nickname = nickname; 66 | } 67 | 68 | public String getAvatar() { 69 | return avatar; 70 | } 71 | 72 | public void setAvatar(String avatar) { 73 | this.avatar = avatar; 74 | } 75 | 76 | public String getDescription() { 77 | return description; 78 | } 79 | 80 | public void setDescription(String description) { 81 | this.description = description; 82 | } 83 | 84 | public String getSex() { 85 | return sex; 86 | } 87 | 88 | public void setSex(String sex) { 89 | this.sex = sex; 90 | } 91 | 92 | public String getLocation() { 93 | return location; 94 | } 95 | 96 | public void setLocation(String location) { 97 | this.location = location; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /app/src/main/java-gen/me/xiezefan/easyim/dao/FriendRequest.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.dao; 2 | 3 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit. 4 | /** 5 | * Entity mapped to table FRIEND_REQUEST. 6 | */ 7 | public class FriendRequest { 8 | 9 | private Long id; 10 | private String uid; 11 | private String username; 12 | private String nickname; 13 | private String displayName; 14 | private String avatar; 15 | private String reason; 16 | private String status; 17 | private Boolean isRead; 18 | private Long createTime; 19 | 20 | public FriendRequest() { 21 | } 22 | 23 | public FriendRequest(Long id) { 24 | this.id = id; 25 | } 26 | 27 | public FriendRequest(Long id, String uid, String username, String nickname, String displayName, String avatar, String reason, String status, Boolean isRead, Long createTime) { 28 | this.id = id; 29 | this.uid = uid; 30 | this.username = username; 31 | this.nickname = nickname; 32 | this.displayName = displayName; 33 | this.avatar = avatar; 34 | this.reason = reason; 35 | this.status = status; 36 | this.isRead = isRead; 37 | this.createTime = createTime; 38 | } 39 | 40 | public Long getId() { 41 | return id; 42 | } 43 | 44 | public void setId(Long id) { 45 | this.id = id; 46 | } 47 | 48 | public String getUid() { 49 | return uid; 50 | } 51 | 52 | public void setUid(String uid) { 53 | this.uid = uid; 54 | } 55 | 56 | public String getUsername() { 57 | return username; 58 | } 59 | 60 | public void setUsername(String username) { 61 | this.username = username; 62 | } 63 | 64 | public String getNickname() { 65 | return nickname; 66 | } 67 | 68 | public void setNickname(String nickname) { 69 | this.nickname = nickname; 70 | } 71 | 72 | public String getDisplayName() { 73 | return displayName; 74 | } 75 | 76 | public void setDisplayName(String displayName) { 77 | this.displayName = displayName; 78 | } 79 | 80 | public String getAvatar() { 81 | return avatar; 82 | } 83 | 84 | public void setAvatar(String avatar) { 85 | this.avatar = avatar; 86 | } 87 | 88 | public String getReason() { 89 | return reason; 90 | } 91 | 92 | public void setReason(String reason) { 93 | this.reason = reason; 94 | } 95 | 96 | public String getStatus() { 97 | return status; 98 | } 99 | 100 | public void setStatus(String status) { 101 | this.status = status; 102 | } 103 | 104 | public Boolean getIsRead() { 105 | return isRead; 106 | } 107 | 108 | public void setIsRead(Boolean isRead) { 109 | this.isRead = isRead; 110 | } 111 | 112 | public Long getCreateTime() { 113 | return createTime; 114 | } 115 | 116 | public void setCreateTime(Long createTime) { 117 | this.createTime = createTime; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/Application.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim; 2 | 3 | import android.database.sqlite.SQLiteDatabase; 4 | 5 | 6 | 7 | import javax.inject.Inject; 8 | 9 | import cn.jpush.android.api.JPushInterface; 10 | import dagger.ObjectGraph; 11 | import me.xiezefan.easyim.dao.DaoMaster; 12 | import me.xiezefan.easyim.dao.DaoSession; 13 | import me.xiezefan.easyim.event.NotificationEventManager; 14 | import me.xiezefan.easyim.module.AndroidModule; 15 | 16 | /** 17 | * EasyIM Application 18 | * Created by XieZeFan on 2015/4/11 0011. 19 | */ 20 | public class Application extends android.app.Application { 21 | private static final String DATABASE_NAME = "EasyImDB"; 22 | private static Application instance; 23 | private DaoSession daoSession; 24 | private ObjectGraph applicationGraph; 25 | 26 | @Inject 27 | NotificationEventManager notificationEventManager; 28 | 29 | @Override 30 | public void onCreate() { 31 | super.onCreate(); 32 | initData(); 33 | initJPush(); 34 | applicationGraph = ObjectGraph.create(new AndroidModule(this)); 35 | applicationGraph.inject(this); 36 | notificationEventManager.register(); 37 | } 38 | 39 | 40 | private void initData() { 41 | instance = this; 42 | DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, DATABASE_NAME, null); 43 | SQLiteDatabase db = helper.getWritableDatabase(); 44 | DaoMaster daoMaster = new DaoMaster(db); 45 | daoSession = daoMaster.newSession(); 46 | } 47 | 48 | 49 | 50 | public ObjectGraph getApplicationGraph() { 51 | return applicationGraph; 52 | } 53 | 54 | public DaoSession getDaoSession() { 55 | return daoSession; 56 | } 57 | 58 | private void initJPush() { 59 | JPushInterface.setDebugMode(true); 60 | JPushInterface.init(this); 61 | } 62 | 63 | public static Application getInstance() { 64 | return instance; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/common/ConstantHelper.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.common; 2 | 3 | /** 4 | * 系统常量 5 | * Created by xiezefan on 15/5/21. 6 | */ 7 | public class ConstantHelper { 8 | public static final String QI_NIU_BUCKET_HOST = "http://7xj4ew.com1.z0.glb.clouddn.com/"; 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/common/DataCleanHelper.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.common; 2 | 3 | import android.content.Context; 4 | import android.os.Environment; 5 | 6 | import java.io.File; 7 | 8 | /** 9 | * Created by xiezefan on 15/5/22. 10 | */ 11 | public class DataCleanHelper { 12 | /** * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache) * * @param context */ 13 | public static void cleanInternalCache(Context context) { 14 | deleteFilesByDirectory(context.getCacheDir()); 15 | } 16 | 17 | /** * 清除本应用所有数据库(/data/data/com.xxx.xxx/databases) * * @param context */ 18 | public static void cleanDatabases(Context context) { 19 | deleteFilesByDirectory(new File("/data/data/" 20 | + context.getPackageName() + "/databases")); 21 | } 22 | 23 | /** 24 | * * 清除本应用SharedPreference(/data/data/com.xxx.xxx/shared_prefs) * * @param 25 | * context 26 | */ 27 | public static void cleanSharedPreference(Context context) { 28 | deleteFilesByDirectory(new File("/data/data/" 29 | + context.getPackageName() + "/shared_prefs")); 30 | } 31 | 32 | /** * 按名字清除本应用数据库 * * @param context * @param dbName */ 33 | public static void cleanDatabaseByName(Context context, String dbName) { 34 | context.deleteDatabase(dbName); 35 | } 36 | 37 | /** * 清除/data/data/com.xxx.xxx/files下的内容 * * @param context */ 38 | public static void cleanFiles(Context context) { 39 | deleteFilesByDirectory(context.getFilesDir()); 40 | } 41 | 42 | /** 43 | * * 清除外部cache下的内容(/mnt/sdcard/android/data/com.xxx.xxx/cache) * * @param 44 | * context 45 | */ 46 | public static void cleanExternalCache(Context context) { 47 | if (Environment.getExternalStorageState().equals( 48 | Environment.MEDIA_MOUNTED)) { 49 | deleteFilesByDirectory(context.getExternalCacheDir()); 50 | } 51 | } 52 | 53 | /** * 清除自定义路径下的文件,使用需小心,请不要误删。而且只支持目录下的文件删除 * * @param filePath */ 54 | public static void cleanCustomCache(String filePath) { 55 | deleteFilesByDirectory(new File(filePath)); 56 | } 57 | 58 | /** * 清除本应用所有的数据 * * @param context * @param filepath */ 59 | public static void cleanApplicationData(Context context, String... filepath) { 60 | cleanInternalCache(context); 61 | cleanExternalCache(context); 62 | cleanDatabases(context); 63 | cleanSharedPreference(context); 64 | cleanFiles(context); 65 | for (String filePath : filepath) { 66 | cleanCustomCache(filePath); 67 | } 68 | } 69 | 70 | /** * 删除方法 这里只会删除某个文件夹下的文件,如果传入的directory是个文件,将不做处理 * * @param directory */ 71 | private static void deleteFilesByDirectory(File directory) { 72 | if (directory != null && directory.exists() && directory.isDirectory()) { 73 | for (File item : directory.listFiles()) { 74 | item.delete(); 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/common/FriendHelper.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.common; 2 | 3 | import android.text.TextUtils; 4 | 5 | import me.xiezefan.easyim.dao.Friend; 6 | 7 | /** 8 | * Friend Entity Helper 9 | * Created by xiezefan on 15/5/16. 10 | */ 11 | public class FriendHelper { 12 | public String getDisplayName(Friend friend) { 13 | if (TextUtils.isEmpty(friend.getNickname())) { 14 | return friend.getUsername(); 15 | } else { 16 | return friend.getNickname(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/common/PromptHelper.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.common; 2 | 3 | import android.app.Notification; 4 | import android.app.NotificationManager; 5 | import android.app.PendingIntent; 6 | import android.app.Service; 7 | import android.content.Context; 8 | import android.content.Intent; 9 | import android.graphics.Color; 10 | import android.media.RingtoneManager; 11 | import android.net.Uri; 12 | import android.os.Vibrator; 13 | import android.support.v4.app.NotificationCompat; 14 | 15 | import java.util.Map; 16 | 17 | import me.xiezefan.easyim.R; 18 | 19 | 20 | /** 21 | * Notification Helper 22 | * Created by XieZeFan on 2015/4/26 0026. 23 | */ 24 | public class PromptHelper { 25 | 26 | public void vibration(Context context) { 27 | if (SPHelper.getBoolean(SPHelper.NOTIFICATION_VIBRATION, false)) { 28 | Vibrator mVibrator = (Vibrator) context.getSystemService(Service.VIBRATOR_SERVICE); 29 | mVibrator.vibrate(new long[] {100,400,100,400}, -1); 30 | } 31 | } 32 | 33 | public void prompt(Context context) { 34 | if (SPHelper.getBoolean(SPHelper.NOTIFICATION_VOICE, true)) { 35 | Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 36 | RingtoneManager.getRingtone(context, notification).play(); 37 | } 38 | } 39 | 40 | public void showBigText(Context context, int notificationId, String title, String text, Intent resultIntent) { 41 | showBigText(context, notificationId, title + ":" + text, title, text, text, resultIntent); 42 | } 43 | 44 | public void showBigText(Context context, int notificationId, 45 | String ticker, String title, 46 | String miniText, String bigText, 47 | Intent resultIntent) { 48 | 49 | PendingIntent contentPendingIntent = PendingIntent.getActivity( 50 | context, notificationId, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT); 51 | 52 | NotificationCompat.Builder builder = new NotificationCompat.Builder(context) 53 | .setSmallIcon(R.drawable.ic_launcher) 54 | .setContentTitle(title) 55 | .setContentText(miniText) 56 | .setTicker(ticker) 57 | .setStyle(new NotificationCompat.BigTextStyle().bigText(bigText)) 58 | .setAutoCancel(true); 59 | 60 | builder.setContentIntent(contentPendingIntent); 61 | showNotification(context, notificationId, builder); 62 | } 63 | 64 | private void showNotification(Context context,int notificationId, NotificationCompat.Builder builder) { 65 | NotificationManager mNotifyMgr = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); 66 | Notification notification = builder.build(); 67 | 68 | if (SPHelper.getBoolean(SPHelper.NOTIFICATION_VIBRATION, true)) { 69 | notification.vibrate = new long[] {100,400,100,400}; 70 | } 71 | if (SPHelper.getBoolean(SPHelper.NOTIFICATION_VIBRATION, true)) { 72 | notification.sound=Uri.parse("android.resource://"+R.class.getPackage().getName()+"/" +R.raw.ping_8); 73 | } 74 | 75 | notification.ledARGB = Color.GREEN;//led灯颜色 76 | notification.ledOffMS = 1000;//关闭时间 毫秒 77 | notification.ledOnMS = 1000;//开启时间 毫秒 78 | notification.flags|=Notification.FLAG_SHOW_LIGHTS; 79 | mNotifyMgr.notify(notificationId, notification); 80 | } 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/common/SPHelper.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.common; 2 | 3 | import android.content.SharedPreferences; 4 | import android.preference.PreferenceManager; 5 | 6 | import me.xiezefan.easyim.Application; 7 | 8 | /** 9 | * Shared Preferences Helper 10 | * Created by XieZeFan on 2015/4/12 0012. 11 | */ 12 | public class SPHelper { 13 | /*----KEY----*/ 14 | public static final String USER_ID = "USER_ID"; 15 | public static final String USERNAME = "USERNAME"; 16 | public static final String NICKNAME = "NICKNAME"; 17 | public static final String USER_AVATAR = "USER_AVATAR"; 18 | public static final String USER_DESCRIPTION = "USER_DESCRIPTION"; 19 | public static final String USER_LOCATION = "USER_LOCATION"; 20 | public static final String USER_SEX = "USER_SEX"; 21 | 22 | public static final String AUTH_CODE = "AUTH_CODE"; 23 | public static final String REGISTER_ID = "REGISTER_ID"; 24 | 25 | public static final String FILE_UPLOAD_TOKEN = "FILE_UPLOAD_TOKEN"; 26 | 27 | // System Profile 28 | public static final String NOTIFICATION_VIBRATION = "NOTIFICATION_VIBRATION"; 29 | public static final String NOTIFICATION_VOICE = "NOTIFICATION_VOICE"; 30 | 31 | public static void clearAll() { 32 | getPreferences().edit().clear().commit(); 33 | } 34 | 35 | public static String getString(String key) { 36 | return getString(key, ""); 37 | } 38 | 39 | public static String getString(String key, String defaultValue) { 40 | return getPreferences().getString(key, defaultValue); 41 | } 42 | 43 | public static boolean setString(String key, String value) { 44 | return getPreferences().edit().putString(key, value).commit(); 45 | } 46 | 47 | public static boolean getBoolean(String key) { 48 | return getBoolean(key, false); 49 | } 50 | 51 | public static boolean getBoolean(String key, boolean defaultValue) { 52 | return getPreferences().getBoolean(key, defaultValue); 53 | } 54 | 55 | public static boolean setBoolean(String key, boolean value) { 56 | return getPreferences().edit().putBoolean(key, value).commit(); 57 | } 58 | 59 | public static int getInt(String key) { 60 | return getInt(key, -1); 61 | } 62 | 63 | public static int getInt(String key, int defaultValue) { 64 | return getPreferences().getInt(key, defaultValue); 65 | } 66 | 67 | public static boolean setInt(String key, int value) { 68 | return getPreferences().edit().putInt(key, value).commit(); 69 | } 70 | 71 | private static SharedPreferences preferences; 72 | private static SharedPreferences getPreferences() { 73 | if (preferences == null) { 74 | preferences = PreferenceManager.getDefaultSharedPreferences(Application.getInstance()); 75 | } 76 | return preferences; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/event/NotificationEventManager.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.event; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.text.TextUtils; 6 | 7 | import com.orhanobut.logger.Logger; 8 | 9 | import java.math.BigDecimal; 10 | import java.util.Random; 11 | 12 | import javax.inject.Inject; 13 | 14 | import de.greenrobot.event.EventBus; 15 | import me.xiezefan.easyim.common.FriendHelper; 16 | import me.xiezefan.easyim.common.PromptHelper; 17 | import me.xiezefan.easyim.dao.ChatItem; 18 | import me.xiezefan.easyim.dao.Friend; 19 | import me.xiezefan.easyim.dao.FriendDao; 20 | import me.xiezefan.easyim.dao.FriendRequest; 21 | import me.xiezefan.easyim.module.ForApplication; 22 | import me.xiezefan.easyim.mvp.chat.ChatActivity; 23 | import me.xiezefan.easyim.mvp.main.MainActivity; 24 | import me.xiezefan.easyim.util.JsonUtil; 25 | 26 | /** 27 | * Notification Event Manager 28 | * Created by XieZeFan on 2015/4/26 0026. 29 | */ 30 | public class NotificationEventManager { 31 | 32 | @Inject 33 | PromptHelper promptHelper; 34 | @Inject 35 | FriendDao friendDao; 36 | @Inject 37 | FriendHelper friendHelper; 38 | 39 | 40 | @Inject 41 | @ForApplication 42 | Context context; 43 | 44 | private Random randomInt; 45 | 46 | /** 47 | * 好友添加请求事件 48 | * @param newFriend 好友对象 49 | */ 50 | public void onEventMainThread(FriendRequest newFriend) { 51 | promptHelper.showBigText(context, 52 | generateNotificationId(), 53 | "好友请求" , 54 | newFriend.getDisplayName() + "请求添加你为好友", 55 | new Intent(context, MainActivity.class)); 56 | } 57 | 58 | /** 59 | * 聊天消息事件 60 | * @param chatItem 聊天消息 61 | */ 62 | public void onEventMainThread(ChatItem chatItem) { 63 | String fromId = chatItem.getFromId(); 64 | String friendName; 65 | String notifyText; 66 | if ('s' == fromId.charAt(0)) { 67 | Friend friend = friendDao.queryBuilder().where(FriendDao.Properties.Uid.eq(fromId)).unique(); 68 | if (friend == null) { 69 | return; 70 | } 71 | friendName = friendHelper.getDisplayName(friend); 72 | notifyText = chatItem.getContent(); 73 | } else { 74 | // TODO generate notifyText when support group chat 75 | friendName = "HelloWorld"; 76 | notifyText = "Generate notifyText when support Group Chat"; 77 | } 78 | 79 | Intent intent = new Intent(context, ChatActivity.class); 80 | intent.putExtra(ChatActivity.KEY_TARGET_ID, fromId); 81 | promptHelper.showBigText(context, 82 | new BigDecimal(chatItem.getChatSessionId()).intValueExact(), 83 | friendName , 84 | notifyText, 85 | intent); 86 | 87 | } 88 | 89 | public int generateNotificationId() { 90 | return randomInt.nextInt(10000); 91 | } 92 | 93 | 94 | 95 | 96 | 97 | 98 | public void register() { 99 | EventBus.getDefault().register(this); 100 | } 101 | 102 | public void unregister() { 103 | EventBus.getDefault().unregister(this); 104 | } 105 | 106 | public NotificationEventManager() { 107 | this.randomInt = new Random(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/event/model/BackPressedEvent.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.event.model; 2 | 3 | import android.app.Activity; 4 | 5 | /** 6 | * 返回按钮按下 事件 7 | * Created by xiezefan-pc on 15-4-28. 8 | */ 9 | public class BackPressedEvent { 10 | public Activity sourceActivity; 11 | 12 | public BackPressedEvent(Activity sourceActivity) { 13 | this.sourceActivity = sourceActivity; 14 | } 15 | 16 | public boolean inSameActivity(Activity activity) { 17 | return sourceActivity == activity; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/event/model/ChatMessageEvent.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.event.model; 2 | 3 | import me.xiezefan.easyim.dao.ChatItem; 4 | import me.xiezefan.easyim.dao.ChatSession; 5 | 6 | /** 7 | * 聊天消息事件 8 | * Created by xiezefan on 15/5/14. 9 | */ 10 | public class ChatMessageEvent { 11 | public Action action; 12 | public ChatItem chatItem; 13 | public ChatSession chatSession; 14 | 15 | public ChatMessageEvent(ChatSession chatSession, ChatItem chatItem, Action action) { 16 | this.chatSession = chatSession; 17 | this.action = action; 18 | this.chatItem = chatItem; 19 | } 20 | 21 | public ChatMessageEvent() { 22 | } 23 | 24 | public enum Action { 25 | RECEIVED, CREATE, UPDATE 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/event/model/FriendRequestEvent.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.event.model; 2 | 3 | /** 4 | * Created by XieZeFan on 2015/4/26 0026. 5 | */ 6 | public class FriendRequestEvent { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/event/model/NewFriendEvent.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.event.model; 2 | 3 | import me.xiezefan.easyim.dao.Friend; 4 | 5 | public class NewFriendEvent { 6 | public Friend friend; 7 | 8 | public NewFriendEvent(Friend friend) { 9 | this.friend = friend; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/event/model/ProcessEvent.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.event.model; 2 | 3 | /** 4 | * 处理状态变化事件 5 | * Created by xiezefan-pc on 15-4-27. 6 | */ 7 | public enum ProcessEvent { 8 | FRIEND_REQUEST_SUCCESS_EVENT; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/model/FriendRequestStatus.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.model; 2 | 3 | /** 4 | * Friend Request Status 5 | * Created by XieZeFan on 2015/4/18 0018. 6 | */ 7 | public enum FriendRequestStatus { 8 | UNTREATED, ACCEPT; 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/model/MessageStatus.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.model; 2 | 3 | /** 4 | * 聊天消息 阶段状态 5 | * Created by xiezefan on 15/5/6. 6 | */ 7 | public enum MessageStatus { 8 | CREATE, 9 | RECEIVED, 10 | READ, 11 | SEND_FAIL 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/model/MessageType.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.model; 2 | 3 | /** 4 | * Created by XieZeFan on 2015/4/25 0025. 5 | */ 6 | public enum MessageType { 7 | // 好友添加请求消息 8 | FRIEND_ADD_REQUEST, 9 | FRIEND_ADD_ACCEPT, 10 | 11 | CHAT_TEXT, 12 | CHAT_TIP, 13 | CHAT_IMAGE, 14 | 15 | 16 | // 未知消息 17 | UN_KNOWN_TYPE; 18 | 19 | 20 | public static MessageType format(String name) { 21 | MessageType result; 22 | try { 23 | result = MessageType.valueOf(name); 24 | } catch (Exception e) { 25 | result = UN_KNOWN_TYPE; 26 | } 27 | return result; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/module/DaoModule.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.module; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | 6 | import javax.inject.Singleton; 7 | 8 | import dagger.Module; 9 | import dagger.Provides; 10 | import me.xiezefan.easyim.dao.DaoMaster; 11 | import me.xiezefan.easyim.dao.DaoSession; 12 | import me.xiezefan.easyim.dao.FriendDao; 13 | import me.xiezefan.easyim.dao.FriendRequestDao; 14 | 15 | /** 16 | * GreenDao注入模块 17 | * Created by xiezefan-pc on 15-4-28. 18 | */ 19 | @Module( 20 | library = true) 21 | public class DaoModule { 22 | private static final String DATABASE_NAME = "EasyImDB"; 23 | private DaoSession daoSession; 24 | 25 | public DaoModule(Context context) { 26 | DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, DATABASE_NAME, null); 27 | SQLiteDatabase db = helper.getWritableDatabase(); 28 | DaoMaster daoMaster = new DaoMaster(db); 29 | daoSession = daoMaster.newSession(); 30 | } 31 | 32 | @Provides 33 | @Singleton 34 | FriendDao provideFriend() {return daoSession.getFriendDao();} 35 | 36 | @Provides 37 | @Singleton 38 | FriendRequestDao provideFriendRequest() {return daoSession.getFriendRequestDao();} 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/module/ForApplication.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.module; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | import javax.inject.Qualifier; 7 | 8 | /** 9 | * 表明注入对象来着Application 10 | * Created by XieZeFan on 2015/4/26 0026. 11 | */ 12 | @Qualifier 13 | @Retention(RetentionPolicy.RUNTIME) 14 | public @interface ForApplication {} 15 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/module/RequestModule.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.module; 2 | 3 | 4 | import javax.inject.Singleton; 5 | 6 | import dagger.Module; 7 | import dagger.Provides; 8 | import me.xiezefan.easyim.dao.FriendRequestDao; 9 | import me.xiezefan.easyim.net.AuthorizationRequestInterceptor; 10 | import me.xiezefan.easyim.net.DefaultErrorHandler; 11 | import me.xiezefan.easyim.net.FriendshipResource; 12 | import me.xiezefan.easyim.net.MessageResource; 13 | import me.xiezefan.easyim.net.UserResource; 14 | import retrofit.RestAdapter; 15 | 16 | /** 17 | * 网络请求注入模块 18 | * Created by xiezefan-pc on 15-4-28. 19 | */ 20 | @Module(library = true) 21 | public class RequestModule { 22 | //private static final String EASY_IM_ENDPOINT = "http://192.168.0.3:8080/EasyIM-Server/"; 23 | private static final String EASY_IM_ENDPOINT = "http://112.124.51.227:8080/easyim/"; 24 | private RestAdapter easyImRestAdapter; 25 | 26 | public RequestModule() { 27 | easyImRestAdapter = new RestAdapter.Builder() 28 | .setEndpoint(EASY_IM_ENDPOINT) 29 | .setRequestInterceptor(new AuthorizationRequestInterceptor()) 30 | .setErrorHandler(new DefaultErrorHandler()) 31 | .build(); 32 | } 33 | 34 | @Provides 35 | @Singleton 36 | public UserResource provideUserResource() { 37 | return easyImRestAdapter.create(UserResource.class); 38 | } 39 | 40 | @Provides 41 | @Singleton 42 | public FriendshipResource provideFriendshipResource() { 43 | return easyImRestAdapter.create(FriendshipResource.class); 44 | } 45 | 46 | @Provides 47 | @Singleton 48 | public MessageResource provideMessageResource() { 49 | return easyImRestAdapter.create(MessageResource.class); 50 | } 51 | 52 | @Provides 53 | @Singleton 54 | public FriendRequestDao provideRequestDao() { 55 | return easyImRestAdapter.create(FriendRequestDao.class); 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/activity/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.activity; 2 | 3 | import android.support.v7.app.ActionBarActivity; 4 | import android.support.v7.widget.Toolbar; 5 | 6 | import butterknife.ButterKnife; 7 | import butterknife.InjectView; 8 | import me.xiezefan.easyim.R; 9 | 10 | /** 11 | * Created by xiezefan-pc on 15-3-17. 12 | */ 13 | public class BaseActivity extends ActionBarActivity { 14 | @InjectView(R.id.toolbar) 15 | protected Toolbar toolbar; 16 | 17 | @Override 18 | public void setContentView(int layoutResID) { 19 | super.setContentView(layoutResID); 20 | ButterKnife.inject(this); 21 | initToolBar(); 22 | } 23 | 24 | private void initToolBar() { 25 | if (toolbar != null) { 26 | beforeInitToolbar(); 27 | setSupportActionBar(toolbar); 28 | afterInitToolbar(); 29 | } 30 | } 31 | 32 | public Toolbar getToolbar() { 33 | return toolbar; 34 | } 35 | 36 | public void afterInitToolbar() { 37 | 38 | } 39 | 40 | public void beforeInitToolbar() { 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/activity/DispatchActivity.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.activity; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import com.orhanobut.logger.Logger; 8 | 9 | import cn.jpush.android.api.JPushInterface; 10 | import me.xiezefan.easyim.mvp.main.MainActivity; 11 | import me.xiezefan.easyim.service.UserService; 12 | 13 | /** 14 | * Dispatch Activity 15 | * Created by XieZeFan on 2015/4/11 0011. 16 | */ 17 | public class DispatchActivity extends Activity { 18 | private UserService userService = UserService.getInstance();; 19 | @Override 20 | protected void onCreate(Bundle savedInstanceState) { 21 | super.onCreate(savedInstanceState); 22 | if (userService.validateLogin()) { 23 | startActivity(new Intent(this, MainActivity.class)); 24 | finish(); 25 | } else { 26 | startActivity(new Intent(this, LoginActivity.class)); 27 | finish(); 28 | } 29 | 30 | } 31 | 32 | @Override 33 | protected void onPause() { 34 | super.onPause(); 35 | JPushInterface.onPause(this); 36 | } 37 | 38 | @Override 39 | protected void onResume() { 40 | super.onResume(); 41 | JPushInterface.onResume(this); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/activity/FriendAddActivity.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.activity; 2 | 3 | /** 4 | * Created by XieZeFan on 2015/4/18 0018. 5 | */ 6 | public class FriendAddActivity extends BaseActivity{ 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/activity/FriendsSquareActivity.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.widget.LinearLayoutManager; 5 | import android.support.v7.widget.RecyclerView; 6 | 7 | import butterknife.InjectView; 8 | import me.xiezefan.easyim.R; 9 | import me.xiezefan.easyim.net.RequestManager; 10 | import me.xiezefan.easyim.net.UserResource; 11 | import me.xiezefan.easyim.mvp.adapter.FriendSquareAdapter; 12 | import rx.android.schedulers.AndroidSchedulers; 13 | import rx.schedulers.Schedulers; 14 | 15 | /** 16 | * Created by XieZeFan on 2015/4/25 0025. 17 | */ 18 | public class FriendsSquareActivity extends BaseActivity { 19 | 20 | @InjectView(R.id.rvFriends) 21 | RecyclerView rvFriends; 22 | 23 | private FriendSquareAdapter friendSquareAdapter; 24 | private UserResource userResource; 25 | 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | setContentView(R.layout.activity_friend_square); 30 | 31 | initRecyclerView(); 32 | initData(); 33 | 34 | } 35 | 36 | private void initRecyclerView() { 37 | rvFriends.setLayoutManager(new LinearLayoutManager(this)); 38 | this.friendSquareAdapter = new FriendSquareAdapter(this); 39 | rvFriends.setAdapter(friendSquareAdapter); 40 | } 41 | 42 | private void initData() { 43 | userResource = RequestManager.getInstance().getUserResource(); 44 | userResource.list(0, 15) 45 | .subscribeOn(Schedulers.io()) 46 | .observeOn(AndroidSchedulers.mainThread()) 47 | .subscribe(list -> friendSquareAdapter.setDataSet(list)); 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/activity/RegisterActivity.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.activity; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.text.TextUtils; 6 | import android.view.View; 7 | import android.widget.EditText; 8 | import android.widget.Toast; 9 | 10 | import com.afollestad.materialdialogs.MaterialDialog; 11 | import com.orhanobut.logger.Logger; 12 | 13 | import butterknife.InjectView; 14 | import butterknife.OnClick; 15 | import me.xiezefan.easyim.R; 16 | import me.xiezefan.easyim.net.RequestManager; 17 | import me.xiezefan.easyim.net.UserResource; 18 | import me.xiezefan.easyim.net.from.RegisterForm; 19 | import me.xiezefan.easyim.net.vo.DefaultResponseVo; 20 | import me.xiezefan.easyim.net.vo.RequestFailError; 21 | import me.xiezefan.easyim.util.JsonUtil; 22 | import me.xiezefan.easyim.util.StringUtil; 23 | import rx.android.app.AppObservable; 24 | 25 | /** 26 | * Created by XieZeFan on 2015/3/23 0023. 27 | */ 28 | public class RegisterActivity extends BaseActivity implements View.OnClickListener { 29 | 30 | @InjectView(R.id.etUsername) 31 | EditText etUsername; 32 | @InjectView(R.id.etPassword) 33 | EditText etPassword; 34 | 35 | 36 | private UserResource userResource; 37 | 38 | 39 | @Override 40 | public void onCreate(Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_register); 43 | initData(); 44 | } 45 | 46 | private void initData() { 47 | userResource = RequestManager.getInstance().getUserResource(); 48 | } 49 | 50 | @Override 51 | public void beforeInitToolbar() { 52 | toolbar.setTitle("注册"); 53 | } 54 | 55 | @Override 56 | public void afterInitToolbar() { 57 | toolbar.setNavigationIcon(R.drawable.ic_action_back); 58 | toolbar.setNavigationOnClickListener(this); 59 | } 60 | 61 | @Override 62 | public void onClick(View v) { 63 | finish(); 64 | } 65 | 66 | 67 | @OnClick(R.id.btnRegister) 68 | public void register(View view) { 69 | Logger.d("In Register"); 70 | String username = etUsername.getText().toString(); 71 | String password = etPassword.getText().toString(); 72 | if (TextUtils.isEmpty(username) || username.trim().length() < 6) { 73 | Toast.makeText(this, "用户名不合规范", Toast.LENGTH_SHORT).show(); 74 | return; 75 | } 76 | if (TextUtils.isEmpty(password) || password.trim().length() < 6) { 77 | Toast.makeText(this, "密码不合规范", Toast.LENGTH_SHORT).show(); 78 | return; 79 | } 80 | password = StringUtil.toMD5(password); 81 | MaterialDialog progressDialog = new MaterialDialog.Builder(this) 82 | .title("网络请求中") 83 | .content("正在注册") 84 | .progress(true, 0).show(); 85 | 86 | RegisterForm dataForm = new RegisterForm(username, password); 87 | AppObservable.bindActivity(this, userResource.register(dataForm)) 88 | .subscribe(defaultResponseVo -> { 89 | Toast.makeText(RegisterActivity.this, "注册成功", Toast.LENGTH_SHORT).show(); 90 | Intent data = new Intent(); 91 | data.putExtra(LoginActivity.KEY_USERNAME, username); 92 | setResult(RESULT_OK, data); 93 | progressDialog.dismiss(); 94 | RegisterActivity.this.finish(); 95 | }, error -> { 96 | RequestFailError _error = (RequestFailError) error; 97 | DefaultResponseVo response = _error.getResponse(); 98 | if (response.code == 1004) { 99 | Toast.makeText(RegisterActivity.this, "用户名已经存在", Toast.LENGTH_SHORT).show(); 100 | } else { 101 | Toast.makeText(RegisterActivity.this, "服务器开了小差, 请稍后再试", Toast.LENGTH_SHORT).show(); 102 | Logger.e("Response:" + JsonUtil.toJson(response)); 103 | } 104 | progressDialog.dismiss(); 105 | }); 106 | 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/activity/SearchActivity.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.activity; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.text.TextUtils; 6 | import android.view.View; 7 | import android.widget.EditText; 8 | import android.widget.TextView; 9 | import android.widget.Toast; 10 | 11 | import butterknife.InjectView; 12 | import butterknife.OnClick; 13 | import me.xiezefan.easyim.R; 14 | import rx.android.widget.WidgetObservable; 15 | 16 | /** 17 | * Created by XieZeFan on 2015/4/21 0021. 18 | */ 19 | public class SearchActivity extends BaseActivity { 20 | 21 | 22 | // Toolbar 23 | @InjectView(R.id.etSearchText) 24 | EditText etSearchText; 25 | @InjectView(R.id.tvSearchText) 26 | TextView tvSearchText; 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_search); 32 | initView(); 33 | } 34 | 35 | private void initView() { 36 | WidgetObservable.text(etSearchText).subscribe(event -> { 37 | String text = event.text().toString(); 38 | tvSearchText.setText(text); 39 | if (text.length() > 0 && text.charAt(text.length() - 1) == '\n') { 40 | text = text.substring(0, text.length() - 1); 41 | etSearchText.setText(text); 42 | etSearchText.setSelection(text.length()); 43 | doSearch(text); 44 | } 45 | }); 46 | } 47 | 48 | private void doSearch(String text) { 49 | if (TextUtils.isEmpty(text)) { 50 | //TODO show error dialog 51 | Toast.makeText(this, "搜索内容不能为空", Toast.LENGTH_SHORT).show(); 52 | return; 53 | } 54 | Intent intent = new Intent(this, SearchResultActivity.class); 55 | intent.putExtra(SearchResultActivity.KEY_SEARCH_TEXT, text); 56 | startActivity(intent); 57 | } 58 | 59 | 60 | 61 | @OnClick(R.id.ivCancel) 62 | public void clearSearchText(View view) { 63 | etSearchText.setText(""); 64 | } 65 | 66 | @OnClick(R.id.llSearchBtnWrapper) 67 | public void doSearch(View view) { 68 | doSearch(etSearchText.getText().toString()); 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/activity/SearchResultActivity.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.widget.LinearLayoutManager; 5 | import android.support.v7.widget.RecyclerView; 6 | 7 | import butterknife.InjectView; 8 | import me.xiezefan.easyim.R; 9 | import me.xiezefan.easyim.mvp.adapter.SearchResultAdapter; 10 | 11 | /** 12 | * Search Result Activity 13 | * Created by XieZeFan on 2015/4/22 0022. 14 | */ 15 | public class SearchResultActivity extends BaseActivity { 16 | public static final String KEY_SEARCH_TEXT = "KEY_SEARCH_TEXT"; 17 | 18 | @InjectView(R.id.rvSearchResult) 19 | RecyclerView rvSearchResult; 20 | 21 | private String searchText; 22 | 23 | 24 | @Override 25 | protected void onCreate(Bundle savedInstanceState) { 26 | super.onCreate(savedInstanceState); 27 | initData(); 28 | setContentView(R.layout.activity_search_result); 29 | initSearchResult(); 30 | 31 | } 32 | 33 | private void initData() { 34 | searchText = getIntent().getStringExtra(KEY_SEARCH_TEXT); 35 | } 36 | 37 | @Override 38 | public void beforeInitToolbar() { 39 | toolbar.setTitle("搜索 " + searchText); 40 | } 41 | 42 | @Override 43 | public void afterInitToolbar() { 44 | toolbar.setNavigationIcon(R.drawable.ic_action_back); 45 | } 46 | 47 | private void initSearchResult() { 48 | rvSearchResult.setLayoutManager(new LinearLayoutManager(this)); 49 | rvSearchResult.setAdapter(new SearchResultAdapter(this)); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/activity/TestActivity.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.activity; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.Toast; 8 | 9 | import com.orhanobut.logger.Logger; 10 | 11 | import butterknife.ButterKnife; 12 | import butterknife.OnClick; 13 | import me.xiezefan.easyim.R; 14 | import me.xiezefan.easyim.mvp.gallery.GalleryActivity; 15 | import me.xiezefan.easyim.mvp.gallery.GalleryInteractor; 16 | import me.xiezefan.easyim.net.RequestManager; 17 | import me.xiezefan.easyim.net.from.RegisterForm; 18 | import me.xiezefan.easyim.net.vo.DefaultResponseVo; 19 | import me.xiezefan.easyim.net.vo.RequestFailError; 20 | import me.xiezefan.easyim.util.JsonUtil; 21 | import rx.Subscriber; 22 | import rx.android.schedulers.AndroidSchedulers; 23 | import rx.schedulers.Schedulers; 24 | 25 | /** 26 | * Created by XieZeFan on 2015/4/12 0012. 27 | */ 28 | public class TestActivity extends Activity { 29 | 30 | @Override 31 | protected void onCreate(Bundle savedInstanceState) { 32 | super.onCreate(savedInstanceState); 33 | setContentView(R.layout.activity_test); 34 | ButterKnife.inject(this); 35 | } 36 | 37 | @OnClick(R.id.btnGallery) 38 | public void toGallery() { 39 | startActivity(new Intent(this, GalleryActivity.class)); 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/base/BaseView.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.base; 2 | 3 | import android.content.Context; 4 | 5 | /** 6 | * Base View Interface 7 | * Created by xiezefan on 15/5/17. 8 | */ 9 | public interface BaseView { 10 | public Context getContext(); 11 | public void showToast(String text); 12 | public void showLoading(String text); 13 | public void hideLoading(); 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/base/SimpleRequestListener.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.base; 2 | 3 | /** 4 | * 通用的请求回调函数 5 | * Created by xiezefan on 15/5/18. 6 | */ 7 | public interface SimpleRequestListener { 8 | public void requestSuccess(String tag); 9 | public void requestFail(String tag); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/base/UserInteractor.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.base; 2 | 3 | /** 4 | * Created by xiezefan on 15/5/18. 5 | */ 6 | public class UserInteractor { 7 | 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/chat/ChatPresenterListener.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.chat; 2 | 3 | import me.xiezefan.easyim.dao.ChatItem; 4 | 5 | /** 6 | * Created by xiezefan on 15/5/9. 7 | */ 8 | public interface ChatPresenterListener { 9 | public void onChatItemSend(ChatItem chatItem); 10 | public void onChatItemStatusChange(ChatItem chatItem); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/chat/ChatView.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.chat; 2 | 3 | import android.content.Context; 4 | import android.net.Uri; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import me.xiezefan.easyim.dao.ChatItem; 10 | import me.xiezefan.easyim.mvp.base.BaseView; 11 | 12 | public interface ChatView extends BaseView { 13 | 14 | public void notifyChatItemChange(List dataSet, int start, int row); 15 | public void clearInputView(); 16 | public void scrollToBottom(); 17 | public void updateToolbarTitle(String title); 18 | public void updateAvatarMap(Map avatarMap); 19 | 20 | public void startGallery(); 21 | public void startImageCrop(Uri uri); 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/chat_session/ChatSessionInteractor.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.chat_session; 2 | 3 | import java.util.List; 4 | 5 | import javax.inject.Inject; 6 | 7 | import me.xiezefan.easyim.dao.ChatItem; 8 | import me.xiezefan.easyim.dao.ChatSession; 9 | import me.xiezefan.easyim.dao.ChatSessionDao; 10 | 11 | public class ChatSessionInteractor { 12 | @Inject 13 | ChatSessionDao chatSessionDao; 14 | 15 | public List loadChatSession(int start, int row) { 16 | return chatSessionDao 17 | .queryBuilder() 18 | .orderDesc(ChatSessionDao.Properties.LastTime) 19 | .offset(start) 20 | .limit(row) 21 | .list(); 22 | } 23 | 24 | public ChatSession getChatSession(ChatItem chatItem) { 25 | return chatSessionDao.queryBuilder().where(ChatSessionDao.Properties.Id.eq(chatItem.getChatSessionId())).unique(); 26 | } 27 | 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/chat_session/ChatSessionPresenter.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.chat_session; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import javax.inject.Inject; 7 | 8 | import me.xiezefan.easyim.dao.ChatItem; 9 | import me.xiezefan.easyim.dao.ChatSession; 10 | 11 | public class ChatSessionPresenter { 12 | 13 | @Inject 14 | ChatSessionInteractor chatSessionInteractor; 15 | 16 | private ChatSessionView chatSessionView; 17 | private List chatSessionList; 18 | 19 | public ChatSessionPresenter() { 20 | chatSessionList = new ArrayList<>(); 21 | } 22 | 23 | public void setChatSessionView(ChatSessionView chatSessionView) { 24 | this.chatSessionView = chatSessionView; 25 | } 26 | 27 | 28 | public void initChatSessionList() { 29 | loadChatSessionList(0, 15); 30 | } 31 | 32 | public void loadChatSessionList(int start, int row) { 33 | List list = chatSessionInteractor.loadChatSession(start, row); 34 | int _start = chatSessionList.size(); 35 | int _row = list.size(); 36 | 37 | chatSessionList.addAll(list); 38 | chatSessionView.notifyChatSessionsChange(chatSessionList, _start, _row); 39 | } 40 | 41 | public void onChatItemClick(int position) { 42 | ChatSession item = chatSessionList.get(position); 43 | item.setUnread(0); 44 | chatSessionView.notifyChatSessionsChange(chatSessionList, position, 0); 45 | chatSessionView.startChatActivity(item.getTargetId()); 46 | } 47 | 48 | public void onReceiveChatItem(ChatItem chatItem) { 49 | int index = -1; 50 | for (int i=0; i 0) { 65 | ChatSession chatSession = chatSessionList.get(index); 66 | chatSessionList.remove(index); 67 | chatSessionList.add(0, chatSession); 68 | chatSessionView.notifyChatSessionsChange(chatSessionList, 0, chatSessionList.size()); 69 | } else { 70 | ChatSession cs = chatSessionInteractor.getChatSession(chatItem); 71 | chatSessionList.add(cs); 72 | chatSessionView.notifyChatSessionsChange(chatSessionList, chatSessionList.size() - 1, 1); 73 | } 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/chat_session/ChatSessionView.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.chat_session; 2 | 3 | import java.util.List; 4 | 5 | import me.xiezefan.easyim.dao.ChatSession; 6 | 7 | public interface ChatSessionView { 8 | public void startChatActivity(String targetId); 9 | public void notifyChatSessionsChange(List dataSet, int start, int row); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/common/FileUploadInteractor.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.common; 2 | 3 | import com.orhanobut.logger.Logger; 4 | import com.qiniu.android.http.ResponseInfo; 5 | import com.qiniu.android.storage.UpCompletionHandler; 6 | import com.qiniu.android.storage.UploadManager; 7 | 8 | import org.json.JSONObject; 9 | 10 | import java.io.File; 11 | 12 | import javax.inject.Inject; 13 | 14 | import me.xiezefan.easyim.mvp.base.SimpleRequestListener; 15 | import me.xiezefan.easyim.net.UploadTokenResource; 16 | import rx.Observable; 17 | import rx.android.schedulers.AndroidSchedulers; 18 | import rx.schedulers.Schedulers; 19 | 20 | /** 21 | * 文件(图片)上传业务方法 22 | * Created by xiezefan on 15/5/20. 23 | */ 24 | public class FileUploadInteractor { 25 | 26 | @Inject 27 | UploadTokenResource uploadTokenResource; 28 | 29 | public void upload(File data, String name, SimpleRequestListener listener) { 30 | uploadTokenResource.getToken() 31 | .subscribeOn(Schedulers.io()) 32 | .observeOn(AndroidSchedulers.mainThread()) 33 | .subscribe(uploadToken -> { 34 | UploadManager uploadManager = new UploadManager(); 35 | uploadManager.put(data, name, uploadToken.token, new UpCompletionHandler() { 36 | @Override 37 | public void complete(String key, ResponseInfo info, JSONObject response) { 38 | listener.requestSuccess("image_upload"); 39 | } 40 | }, null); 41 | }, error -> { 42 | Logger.d("Request Fail"); 43 | listener.requestFail("image_upload"); 44 | }); 45 | 46 | } 47 | 48 | public void upload(byte[] data, String name, SimpleRequestListener listener) { 49 | uploadTokenResource.getToken() 50 | .subscribeOn(Schedulers.io()) 51 | .observeOn(AndroidSchedulers.mainThread()) 52 | .subscribe(uploadToken -> { 53 | UploadManager uploadManager = new UploadManager(); 54 | uploadManager.put(data, name, uploadToken.token, new UpCompletionHandler() { 55 | @Override 56 | public void complete(String key, ResponseInfo info, JSONObject response) { 57 | listener.requestSuccess("image_upload"); 58 | } 59 | }, null); 60 | }, error -> { 61 | Logger.d("Request Fail"); 62 | listener.requestFail("image_upload"); 63 | }); 64 | } 65 | 66 | private Observable getToken() { 67 | return null; 68 | 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/common/RoundedTransformation.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.common; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapShader; 5 | import android.graphics.Canvas; 6 | import android.graphics.Paint; 7 | 8 | import com.squareup.picasso.Transformation; 9 | 10 | /** 11 | * Picasso Image Transformation 12 | * Created by XieZeFan on 2015/4/19 0019. 13 | */ 14 | public class RoundedTransformation implements Transformation { 15 | @Override 16 | public Bitmap transform(Bitmap source) { 17 | int size = Math.min(source.getWidth(), source.getHeight()); 18 | 19 | // 对原图裁剪出一个正方形 20 | int x = (source.getWidth() - size) / 2; 21 | int y = (source.getHeight() - size) / 2; 22 | Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size); 23 | if (squaredBitmap != source) { 24 | source.recycle(); 25 | } 26 | 27 | Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig()); 28 | 29 | Canvas canvas = new Canvas(bitmap); 30 | Paint paint = new Paint(); 31 | BitmapShader bitmapShader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP); 32 | paint.setShader(bitmapShader); 33 | paint.setAntiAlias(true); 34 | 35 | float r = size / 2f; 36 | canvas.drawCircle(r, r, r, paint); 37 | squaredBitmap.recycle(); 38 | return bitmap; 39 | } 40 | 41 | @Override 42 | public String key() { 43 | return "circle"; 44 | } 45 | } -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/contact/ContactPresenter.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.contact; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import javax.inject.Inject; 9 | 10 | import de.greenrobot.dao.query.QueryBuilder; 11 | import de.greenrobot.dao.query.WhereCondition; 12 | import me.xiezefan.easyim.dao.Friend; 13 | import me.xiezefan.easyim.dao.FriendDao; 14 | 15 | /** 16 | * ContactFragment Presenter 17 | * Created by xiezefan on 15/5/4. 18 | */ 19 | public class ContactPresenter { 20 | private ContactView contactView; 21 | 22 | @Inject 23 | FriendDao friendDao; 24 | 25 | private List friendSet; 26 | private List searchResultSet; 27 | 28 | public ContactPresenter() { 29 | this.friendSet = new ArrayList<>(); 30 | } 31 | 32 | public void setContactView(ContactView contactView) { 33 | this.contactView = contactView; 34 | } 35 | 36 | /** 37 | * 初始读取好友列表 38 | */ 39 | public void initFriendList() { 40 | loadFriendList(0, 15); 41 | } 42 | 43 | /** 44 | * 读取好友列表 45 | * @param start 偏移值 46 | * @param row 行数 47 | */ 48 | public void loadFriendList(int start, int row) { 49 | List list = friendDao.queryBuilder() 50 | .orderAsc(FriendDao.Properties.Username) 51 | .offset(start) 52 | .limit(row) 53 | .list(); 54 | friendSet.addAll(list); 55 | contactView.notifyContactListChange(friendSet, start, row); 56 | } 57 | 58 | /** 59 | * item 点击事件 60 | * @param position 下标 61 | */ 62 | public void onContactItemClick(int position) { 63 | Friend item; 64 | if (contactView.getCurrentContactList() == friendSet) { 65 | item = friendSet.get(position); 66 | } else { 67 | item = searchResultSet.get(position); 68 | } 69 | contactView.startFriendHomeActivity(item); 70 | } 71 | 72 | /** 73 | * 搜索好友 74 | * @param text 搜索关键字 75 | */ 76 | public void searchFriend(String text) { 77 | if (TextUtils.isEmpty(text)) { 78 | if (contactView.getCurrentContactList() != friendSet) { 79 | contactView.notifyContactListChange(friendSet, 0, searchResultSet.size()); 80 | } 81 | return; 82 | } 83 | 84 | QueryBuilder qb = friendDao.queryBuilder(); 85 | WhereCondition whereCondition = qb.or(FriendDao.Properties.Nickname.like("%" + text + "%"), FriendDao.Properties.Username.like("%" + text + "%")); 86 | searchResultSet = qb.where(whereCondition).orderAsc(FriendDao.Properties.Username).limit(30).list(); 87 | contactView.notifyContactListChange(searchResultSet, 0, searchResultSet.size()); 88 | } 89 | 90 | public void onFriendSetLastItemChange(int lastItemPosition) { 91 | 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/contact/ContactView.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.contact; 2 | 3 | import java.util.List; 4 | 5 | import me.xiezefan.easyim.dao.Friend; 6 | 7 | /** 8 | * ContactFragment 9 | * Created by xiezefan on 15/5/4. 10 | */ 11 | public interface ContactView { 12 | 13 | public void startFriendHomeActivity(Friend friend); 14 | 15 | public void notifyContactListChange(List dataSet, int start, int row); 16 | 17 | public List getCurrentContactList(); 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/friend_home/FriendHomeActivity.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.friend_home; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.text.TextUtils; 7 | import android.view.View; 8 | import android.widget.ImageView; 9 | import android.widget.TextView; 10 | 11 | 12 | import com.squareup.picasso.Picasso; 13 | 14 | import javax.inject.Inject; 15 | 16 | import butterknife.InjectView; 17 | import butterknife.OnClick; 18 | import me.xiezefan.easyim.Application; 19 | import me.xiezefan.easyim.R; 20 | import me.xiezefan.easyim.dao.Friend; 21 | import me.xiezefan.easyim.mvp.activity.BaseActivity; 22 | import me.xiezefan.easyim.mvp.chat.ChatActivity; 23 | import me.xiezefan.easyim.mvp.common.RoundedTransformation; 24 | import me.xiezefan.easyim.util.DisplayUtil; 25 | 26 | /** 27 | * 好友主页 28 | * Created by xiezefan on 15/4/30. 29 | */ 30 | public class FriendHomeActivity extends BaseActivity implements FriendHomeView { 31 | public static final String KEY_FRIEND_ID = "KEY_FRIEND_ID"; 32 | 33 | @InjectView(R.id.ivAvatar) 34 | ImageView ivAvatar; 35 | @InjectView(R.id.tvUsername) 36 | TextView tvUsername; 37 | @InjectView(R.id.tvDescription) 38 | TextView tvDescription; 39 | 40 | @Inject 41 | FriendHomePresenter friendHomePresenter; 42 | 43 | @Override 44 | protected void onCreate(@Nullable Bundle savedInstanceState) { 45 | super.onCreate(savedInstanceState); 46 | setContentView(R.layout.activity_friend_home); 47 | initData(); 48 | } 49 | 50 | private void initData() { 51 | ((Application) getApplication()).getApplicationGraph().inject(this); 52 | friendHomePresenter.setFriendHomeView(this); 53 | 54 | 55 | Intent intent = getIntent(); 56 | String friendId = intent.getStringExtra(KEY_FRIEND_ID); 57 | friendHomePresenter.loadFriend(friendId); 58 | } 59 | 60 | 61 | @Override 62 | public void beforeInitToolbar() { 63 | toolbar.setTitle("用户信息"); 64 | } 65 | 66 | @Override 67 | public void afterInitToolbar() { 68 | toolbar.setNavigationIcon(R.drawable.ic_action_back); 69 | toolbar.setNavigationOnClickListener(v -> finish()); 70 | } 71 | 72 | @OnClick(R.id.btnChat) 73 | public void btnChat(View view) { 74 | friendHomePresenter.onChatBtnClick(); 75 | } 76 | 77 | @Override 78 | public void startChatActivity(String targetId) { 79 | Intent intent = new Intent(this, ChatActivity.class); 80 | intent.putExtra(ChatActivity.KEY_TARGET_ID, targetId); 81 | startActivity(intent); 82 | } 83 | 84 | @Override 85 | public void bindFriendData(Friend friend) { 86 | int avatarSize = DisplayUtil.dip2px(this, 48); 87 | String displayName = TextUtils.isEmpty(friend.getNickname()) ? friend.getUsername() : friend.getNickname(); 88 | String description = TextUtils.isEmpty(friend.getDescription()) ? "该同学好懒,什么都没留下" : friend.getDescription(); 89 | tvUsername.setText(displayName); 90 | tvDescription.setText(description); 91 | if (!TextUtils.isEmpty(friend.getAvatar())) { 92 | Picasso.with(this) 93 | .load(friend.getAvatar()) 94 | .resize(avatarSize, avatarSize) 95 | .placeholder(getResources().getDrawable(R.drawable.default_user_profile)) 96 | .transform(new RoundedTransformation()) 97 | .into(ivAvatar); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/friend_home/FriendHomePresenter.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.friend_home; 2 | 3 | import javax.inject.Inject; 4 | 5 | import me.xiezefan.easyim.dao.Friend; 6 | import me.xiezefan.easyim.dao.FriendDao; 7 | 8 | public class FriendHomePresenter { 9 | 10 | @Inject 11 | FriendDao friendDao; 12 | 13 | private FriendHomeView friendHomeView; 14 | private Friend friend; 15 | 16 | public FriendHomePresenter() { 17 | 18 | } 19 | 20 | public void setFriendHomeView(FriendHomeView friendHomeView) { 21 | this.friendHomeView = friendHomeView; 22 | } 23 | 24 | public void onChatBtnClick() { 25 | friendHomeView.startChatActivity(friend.getUid()); 26 | } 27 | 28 | public void loadFriend(String friendId) { 29 | friend = friendDao.queryBuilder().where(FriendDao.Properties.Uid.eq(friendId)).unique(); 30 | friendHomeView.bindFriendData(friend); 31 | } 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/friend_home/FriendHomeView.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.friend_home; 2 | 3 | import me.xiezefan.easyim.dao.Friend; 4 | 5 | public interface FriendHomeView { 6 | 7 | public void startChatActivity(String targetId); 8 | 9 | public void bindFriendData(Friend friend); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/gallery/GalleryActivity.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.gallery; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v7.widget.GridLayoutManager; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | import android.support.v7.widget.RecyclerView; 9 | import android.support.v7.widget.StaggeredGridLayoutManager; 10 | import android.view.View; 11 | 12 | import com.afollestad.materialdialogs.MaterialDialog; 13 | 14 | import java.util.List; 15 | 16 | import javax.inject.Inject; 17 | 18 | import butterknife.InjectView; 19 | import me.xiezefan.easyim.Application; 20 | import me.xiezefan.easyim.R; 21 | import me.xiezefan.easyim.mvp.activity.BaseActivity; 22 | 23 | /** 24 | * Gallery 25 | * Created by xiezefan on 15/5/16. 26 | */ 27 | public class GalleryActivity extends BaseActivity implements GalleryView, GalleryAdapter.GalleryListener { 28 | @InjectView(R.id.rvGallery) 29 | RecyclerView rvGallery; 30 | @Inject 31 | GalleryPresenter galleryPresenter; 32 | 33 | private GalleryAdapter galleryAdapter; 34 | private MaterialDialog progressDialog; 35 | 36 | @Override 37 | protected void onCreate(@Nullable Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | setContentView(R.layout.activity_gallery); 40 | initView(); 41 | } 42 | 43 | private void initView() { 44 | ((Application) getApplication()).getApplicationGraph().inject(this); 45 | galleryAdapter = new GalleryAdapter(this); 46 | StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL); 47 | rvGallery.setLayoutManager(layoutManager); 48 | rvGallery.setAdapter(galleryAdapter); 49 | 50 | galleryPresenter.setGalleryView(this); 51 | galleryPresenter.initData(); 52 | 53 | } 54 | 55 | 56 | @Override 57 | public void beforeInitToolbar() { 58 | toolbar.setTitle("选择图片"); 59 | } 60 | 61 | @Override 62 | public void afterInitToolbar() { 63 | toolbar.setNavigationIcon(R.drawable.ic_action_back); 64 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 65 | @Override 66 | public void onClick(View v) { 67 | finish(); 68 | } 69 | }); 70 | } 71 | 72 | @Override 73 | public void notifyDataSetChange(List dataSet, int start, int row) { 74 | galleryAdapter.setDataSet(dataSet); 75 | galleryAdapter.notifyDataSetChanged(); 76 | } 77 | 78 | @Override 79 | public void toPhotoCropActivity(String photo) { 80 | 81 | } 82 | 83 | @Override 84 | public void toCameraActivity() { 85 | 86 | } 87 | 88 | @Override 89 | public Context getContext() { 90 | return this; 91 | } 92 | 93 | @Override 94 | public void showToast(String text) { 95 | 96 | } 97 | 98 | @Override 99 | public void showLoading(String text) { 100 | progressDialog = new MaterialDialog.Builder(this) 101 | .content(text) 102 | .progress(true, 0).show(); 103 | } 104 | 105 | @Override 106 | public void hideLoading() { 107 | progressDialog.hide(); 108 | } 109 | 110 | @Override 111 | public void onCameraItemClick() { 112 | 113 | } 114 | 115 | @Override 116 | public void onImageItemClick(int position) { 117 | 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/gallery/GalleryInteractor.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.gallery; 2 | 3 | import android.content.ContentResolver; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.net.Uri; 7 | import android.provider.MediaStore; 8 | 9 | import com.orhanobut.logger.Logger; 10 | 11 | import java.io.File; 12 | import java.util.ArrayList; 13 | import java.util.HashMap; 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | public class GalleryInteractor { 18 | 19 | 20 | 21 | public Map> scanImage(Context context) { 22 | Map> imageGroupMap = new HashMap<>(); 23 | Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 24 | ContentResolver mContentResolver = context.getContentResolver(); 25 | 26 | //只查询jpeg和png的图片 27 | Cursor mCursor = mContentResolver.query(mImageUri, null, 28 | MediaStore.Images.Media.MIME_TYPE + "=? or " 29 | + MediaStore.Images.Media.MIME_TYPE + "=?", 30 | new String[] { "image/jpeg", "image/png" }, MediaStore.Images.Media.DATE_MODIFIED); 31 | 32 | if(mCursor == null){ 33 | return imageGroupMap; 34 | } 35 | 36 | while (mCursor.moveToNext()) { 37 | //获取图片的路径 38 | String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA)); 39 | //获取该图片的父路径名 40 | String parentName = new File(path).getParentFile().getName(); 41 | //根据父路径名将图片放入到mGroupMap中 42 | if (!imageGroupMap.containsKey(parentName)) { 43 | List chileList = new ArrayList(); 44 | chileList.add(path); 45 | imageGroupMap.put(parentName, chileList); 46 | } else { 47 | imageGroupMap.get(parentName).add(path); 48 | } 49 | } 50 | return imageGroupMap; 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/gallery/GalleryPresenter.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.gallery; 2 | 3 | import android.content.Context; 4 | 5 | import com.orhanobut.logger.Logger; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import javax.inject.Inject; 11 | 12 | import me.xiezefan.easyim.util.JsonUtil; 13 | import rx.Observable; 14 | import rx.android.schedulers.AndroidSchedulers; 15 | import rx.schedulers.Schedulers; 16 | 17 | public class GalleryPresenter { 18 | 19 | @Inject 20 | GalleryInteractor galleryInteractor; 21 | 22 | private GalleryView galleryView; 23 | private List photos; 24 | 25 | public GalleryPresenter() { 26 | photos = new ArrayList<>(); 27 | } 28 | 29 | public void setGalleryView(GalleryView galleryView) { 30 | this.galleryView = galleryView; 31 | } 32 | 33 | public void initData() { 34 | galleryView.showLoading("正在扫描图片"); 35 | Observable.just(galleryInteractor.scanImage(galleryView.getContext())) 36 | .subscribeOn(Schedulers.io()) 37 | .observeOn(AndroidSchedulers.mainThread()) 38 | .subscribe(map -> { 39 | for (String key : map.keySet()) { 40 | photos.addAll(map.get(key)); 41 | } 42 | Logger.d("Photos:" + JsonUtil.toJson(photos)); 43 | galleryView.notifyDataSetChange(photos, 0, photos.size()); 44 | galleryView.hideLoading(); 45 | }, error -> Logger.e(error.getMessage())); 46 | 47 | } 48 | 49 | public void onCameraItemClick() { 50 | galleryView.toCameraActivity(); 51 | } 52 | 53 | public void onPhotoItemClick(int position) { 54 | galleryView.toPhotoCropActivity(photos.get(position)); 55 | } 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/gallery/GalleryView.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.gallery; 2 | 3 | import java.util.List; 4 | 5 | import me.xiezefan.easyim.mvp.base.BaseView; 6 | 7 | public interface GalleryView extends BaseView { 8 | 9 | public void notifyDataSetChange(List dataSet, int start, int row); 10 | public void toPhotoCropActivity(String photo); 11 | public void toCameraActivity(); 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/interactor/FriendInteractor.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.interactor; 2 | 3 | import javax.inject.Inject; 4 | 5 | import me.xiezefan.easyim.dao.Friend; 6 | import me.xiezefan.easyim.dao.FriendDao; 7 | 8 | /** 9 | * Created by xiezefan on 15/5/16. 10 | */ 11 | public class FriendInteractor { 12 | @Inject 13 | FriendDao friendDao; 14 | 15 | public Friend findByUID(String userId) { 16 | return friendDao.queryBuilder().where(FriendDao.Properties.Uid.eq(userId)).unique(); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/main/#MainActivity.java#: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/java/me/xiezefan/easyim/mvp/main/#MainActivity.java# -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/main/MainInteractor.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.main; 2 | 3 | import com.orhanobut.logger.Logger; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import javax.inject.Inject; 11 | 12 | import me.xiezefan.easyim.dao.Friend; 13 | import me.xiezefan.easyim.dao.FriendDao; 14 | import me.xiezefan.easyim.net.FriendshipResource; 15 | import me.xiezefan.easyim.net.vo.UserVo; 16 | import rx.schedulers.Schedulers; 17 | 18 | public class MainInteractor { 19 | @Inject 20 | FriendshipResource friendshipResource; 21 | @Inject 22 | FriendDao friendDao; 23 | 24 | public void synchronizationContact() { 25 | Map friendMapper = new HashMap(); 26 | List localFriends = friendDao.loadAll(); 27 | 28 | for (Friend friend : localFriends) { 29 | friendMapper.put(friend.getUid(), friend); 30 | } 31 | 32 | friendshipResource.list() 33 | .subscribeOn(Schedulers.io()) 34 | .observeOn(Schedulers.io()) 35 | .subscribe(list -> { 36 | List currentFriends = new ArrayList<>(); 37 | for (UserVo userVo : list) { 38 | Friend friend = friendMapper.get(userVo.id); 39 | if (friend == null) { 40 | friend = userVo.generateFriend(); 41 | } else { 42 | friend = userVo.fixFriend(friend); 43 | } 44 | currentFriends.add(friend); 45 | } 46 | friendDao.insertOrReplaceInTx(currentFriends); 47 | Logger.d(String.format("Update %s friends", currentFriends.size())); 48 | }, error -> Logger.e("Update friends fail.")); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/main/MainPresenter.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.main; 2 | 3 | import javax.inject.Inject; 4 | 5 | public class MainPresenter { 6 | @Inject 7 | MainInteractor mainInteractor; 8 | 9 | private MainView mainView; 10 | 11 | public MainPresenter() { 12 | } 13 | 14 | public void setMainView(MainView mainView) { 15 | this.mainView = mainView; 16 | } 17 | 18 | public void syncData() { 19 | mainInteractor.synchronizationContact(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/main/MainView.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.main; 2 | 3 | /** 4 | * Created by xiezefan on 15/5/9. 5 | */ 6 | public interface MainView { 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/new_friend/#NewFriendFragment.java#: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/java/me/xiezefan/easyim/mvp/new_friend/#NewFriendFragment.java# -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/new_friend/FriendAddCallback.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.new_friend; 2 | 3 | import me.xiezefan.easyim.dao.Friend; 4 | import me.xiezefan.easyim.dao.FriendRequest; 5 | 6 | /** 7 | * 添加好友监听器 8 | * Created by XieZeFan on 2015/4/28 0028. 9 | */ 10 | public interface FriendAddCallback { 11 | public void onAddFriendSuccess(FriendRequest request, Friend friend); 12 | public void onAddFriendFail(); 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/new_friend/NewFriendInteractor.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.new_friend; 2 | 3 | 4 | 5 | 6 | import com.orhanobut.logger.Logger; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | import javax.inject.Inject; 12 | 13 | import me.xiezefan.easyim.common.FriendHelper; 14 | import me.xiezefan.easyim.common.SPHelper; 15 | import me.xiezefan.easyim.dao.Friend; 16 | import me.xiezefan.easyim.dao.FriendDao; 17 | import me.xiezefan.easyim.dao.FriendRequest; 18 | import me.xiezefan.easyim.dao.FriendRequestDao; 19 | import me.xiezefan.easyim.model.FriendRequestStatus; 20 | import me.xiezefan.easyim.model.MessageType; 21 | import me.xiezefan.easyim.net.FriendshipResource; 22 | import me.xiezefan.easyim.net.MessageResource; 23 | import me.xiezefan.easyim.net.UserResource; 24 | import me.xiezefan.easyim.net.from.FriendshipAddForm; 25 | import me.xiezefan.easyim.net.from.MessageSendForm; 26 | import rx.Observable; 27 | import rx.android.schedulers.AndroidSchedulers; 28 | import rx.schedulers.Schedulers; 29 | 30 | public class NewFriendInteractor { 31 | @Inject 32 | FriendshipResource friendshipResource; 33 | @Inject 34 | UserResource userResource; 35 | @Inject 36 | MessageResource messageResource; 37 | @Inject 38 | FriendDao friendDao; 39 | @Inject 40 | FriendRequestDao friendRequestDao; 41 | 42 | 43 | 44 | public void addFriend(FriendRequest friendRequest, FriendAddCallback callback) { 45 | FriendshipAddForm dataForm = new FriendshipAddForm(); 46 | dataForm.friend_id = friendRequest.getUid(); 47 | 48 | MessageSendForm msgSendForm = new MessageSendForm(); 49 | msgSendForm.setTo(friendRequest.getUid()); 50 | msgSendForm.setType(MessageType.FRIEND_ADD_ACCEPT.name()); 51 | Map content = new HashMap<>(); 52 | content.put("uid", SPHelper.getString(SPHelper.USER_ID)); 53 | msgSendForm.setContent(content); 54 | 55 | Observable.zip(friendshipResource.save(dataForm), 56 | userResource.getUserInfo(friendRequest.getUid()), 57 | messageResource.send(msgSendForm), 58 | (response, userVo, msgVo) -> { 59 | Friend friend = friendDao.queryBuilder().where(FriendDao.Properties.Uid.eq(friendRequest.getUid())).unique(); 60 | if (friend == null) { 61 | friend = new Friend(); 62 | friend.setUid(friendRequest.getUid()); 63 | friend.setUsername(userVo.username); 64 | friend.setNickname(userVo.nickname); 65 | friend.setAvatar(userVo.avatar); 66 | friendDao.insert(friend); 67 | } 68 | // update friendRequest 69 | friendRequest.setStatus(FriendRequestStatus.ACCEPT.name()); 70 | friendRequestDao.update(friendRequest); 71 | return friend; 72 | }) 73 | .subscribeOn(Schedulers.io()) 74 | .observeOn(AndroidSchedulers.mainThread()) 75 | .subscribe( 76 | friend->callback.onAddFriendSuccess(friendRequest, friend), 77 | error -> { 78 | Logger.d(error.getMessage()); 79 | callback.onAddFriendFail(); 80 | }); 81 | 82 | } 83 | 84 | 85 | } 86 | 87 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/new_friend/NewFriendPresenter.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.new_friend; 2 | 3 | 4 | 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import javax.inject.Inject; 10 | 11 | import de.greenrobot.event.EventBus; 12 | import me.xiezefan.easyim.dao.Friend; 13 | import me.xiezefan.easyim.dao.FriendRequest; 14 | import me.xiezefan.easyim.dao.FriendRequestDao; 15 | import me.xiezefan.easyim.event.model.NewFriendEvent; 16 | 17 | public class NewFriendPresenter implements FriendAddCallback { 18 | 19 | @Inject 20 | NewFriendInteractor newFriendInteractor; 21 | @Inject 22 | FriendRequestDao friendRequestDao; 23 | 24 | private NewFriendView newFriendView; 25 | private List friendRequests; 26 | 27 | public NewFriendPresenter() { 28 | this.friendRequests = new ArrayList<>(); 29 | } 30 | 31 | public void setNewFriendView(NewFriendView newFriendView) { 32 | this.newFriendView = newFriendView; 33 | } 34 | 35 | public void onFriendRequestItemClick(int position) { 36 | newFriendView.showProgress(); 37 | FriendRequest item = friendRequests.get(position); 38 | newFriendInteractor.addFriend(item, this); 39 | } 40 | 41 | public void cancelCurrentRequest() {} 42 | 43 | public void initFriendRequests() { 44 | loadFriendRequests(0, 15); 45 | } 46 | 47 | public void onLastVisibleItemChange(int lastVisiblePosition) { 48 | 49 | } 50 | 51 | private void loadFriendRequests(int start, int row) { 52 | List list = friendRequestDao.queryBuilder() 53 | .orderDesc(FriendRequestDao.Properties.CreateTime) 54 | .offset(start) 55 | .limit(row) 56 | .list(); 57 | int oldSize = friendRequests.size(); 58 | friendRequests.addAll(list); 59 | newFriendView.notifyFriendRequestsChange(friendRequests, oldSize, row); 60 | } 61 | 62 | public void onReceiveNewFriendRequest(FriendRequest request) { 63 | friendRequests.add(0, request); 64 | newFriendView.notifyFriendRequestsChange(friendRequests, 0, friendRequests.size()); 65 | } 66 | 67 | 68 | /** 69 | * 添加好友成功的回调 70 | * @param friendRequest 添加好友的请求对象 71 | */ 72 | @Override 73 | public void onAddFriendSuccess(FriendRequest friendRequest, Friend friend) { 74 | int position = friendRequests.indexOf(friendRequest); 75 | newFriendView.hideProgress(); 76 | if (position >= 0) { 77 | newFriendView.notifyFriendRequestsChange(friendRequests, position, 0); 78 | } 79 | EventBus.getDefault().post(new NewFriendEvent(friend)); 80 | 81 | newFriendView.startFriendHomeActivity(friend); 82 | } 83 | 84 | @Override 85 | public void onAddFriendFail() { 86 | newFriendView.hideProgress(); 87 | newFriendView.showToast("添加好友失败, 请稍后重试"); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/new_friend/NewFriendView.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.new_friend; 2 | 3 | import java.util.List; 4 | 5 | import me.xiezefan.easyim.dao.Friend; 6 | import me.xiezefan.easyim.dao.FriendRequest; 7 | 8 | public interface NewFriendView { 9 | 10 | public void showProgress(); 11 | 12 | public void hideProgress(); 13 | 14 | public void showToast(String text); 15 | 16 | public void notifyFriendRequestsChange(List dataSet, int start, int end); 17 | 18 | public void startFriendHomeActivity(Friend friend); 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/user_info/UserInfoInteractor.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.user_info; 2 | 3 | import javax.inject.Inject; 4 | 5 | import me.xiezefan.easyim.common.SPHelper; 6 | import me.xiezefan.easyim.dao.ChatItemDao; 7 | import me.xiezefan.easyim.dao.ChatSessionDao; 8 | import me.xiezefan.easyim.dao.FriendDao; 9 | import me.xiezefan.easyim.dao.FriendRequestDao; 10 | import me.xiezefan.easyim.mvp.base.SimpleRequestListener; 11 | import me.xiezefan.easyim.net.UserResource; 12 | import me.xiezefan.easyim.net.from.UserUpdateForm; 13 | import rx.android.schedulers.AndroidSchedulers; 14 | import rx.schedulers.Schedulers; 15 | 16 | public class UserInfoInteractor { 17 | 18 | @Inject 19 | UserResource userResource; 20 | @Inject 21 | FriendDao friendDao; 22 | @Inject 23 | FriendRequestDao friendRequestDao; 24 | @Inject 25 | ChatSessionDao chatSessionDao; 26 | @Inject 27 | ChatItemDao chatItemDao; 28 | 29 | public void updateUserInfo(String key, String value, SimpleRequestListener listener) { 30 | UserUpdateForm dataForm = new UserUpdateForm(key, value); 31 | userResource.update(dataForm) 32 | .subscribeOn(Schedulers.io()) 33 | .observeOn(AndroidSchedulers.mainThread()) 34 | .subscribe(response -> { 35 | listener.requestSuccess(key); 36 | if ("nickname".equals(key)) { 37 | SPHelper.setString(SPHelper.NICKNAME, value); 38 | } else if ("avatar".equals(key)) { 39 | SPHelper.setString(SPHelper.USER_AVATAR, value); 40 | } else if ("sex".equals(key)) { 41 | SPHelper.setString(SPHelper.USER_SEX, value); 42 | } else if ("description".equals(key)) { 43 | SPHelper.setString(SPHelper.USER_DESCRIPTION, value); 44 | } else if ("location".equals(key)) { 45 | SPHelper.setString(SPHelper.USER_LOCATION, value); 46 | } 47 | }, error -> listener.requestFail(key)); 48 | } 49 | 50 | 51 | public void cleanAllData() { 52 | friendDao.deleteAll(); 53 | friendRequestDao.deleteAll(); 54 | chatSessionDao.deleteAll(); 55 | chatItemDao.deleteAll(); 56 | SPHelper.clearAll(); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/mvp/user_info/UserInfoView.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.mvp.user_info; 2 | 3 | import android.net.Uri; 4 | 5 | import java.util.Map; 6 | 7 | import me.xiezefan.easyim.mvp.base.BaseView; 8 | 9 | public interface UserInfoView extends BaseView { 10 | public void notifyDataSetChange(Map dataSet); 11 | 12 | public void startImageCrop(Uri uri); 13 | public void startGallery(); 14 | 15 | public void showTextEditor(String tag, String hint, String preFill); 16 | public void showSexEditor(); 17 | public void showPhotoSelector(); 18 | 19 | public void toLoginActivity(); 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/AuthorizationRequestInterceptor.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.orhanobut.logger.Logger; 6 | 7 | import me.xiezefan.easyim.common.SPHelper; 8 | import retrofit.RequestInterceptor; 9 | 10 | /** 11 | * Authorization Request Interceptor 12 | * Created by XieZeFan on 2015/4/12 0012. 13 | */ 14 | public class AuthorizationRequestInterceptor implements RequestInterceptor { 15 | @Override 16 | public void intercept(RequestFacade request) { 17 | request.addHeader("User-Agent", "EasyIM-V1-Android"); 18 | String authCode = SPHelper.getString(SPHelper.AUTH_CODE); 19 | if (!TextUtils.isEmpty(authCode)) { 20 | request.addHeader("Authorization", authCode); 21 | } 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/DefaultErrorHandler.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net; 2 | 3 | import me.xiezefan.easyim.net.vo.RequestFailError; 4 | import retrofit.ErrorHandler; 5 | import retrofit.RetrofitError; 6 | 7 | /** 8 | * Process DefaultResponseVo ErrorHandler 9 | * Created by XieZeFan on 2015/4/12 0012. 10 | */ 11 | public class DefaultErrorHandler implements ErrorHandler { 12 | @Override 13 | public Throwable handleError(RetrofitError cause) { 14 | return new RequestFailError(cause); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/FriendshipResource.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net; 2 | 3 | 4 | import java.util.List; 5 | 6 | import me.xiezefan.easyim.net.from.FriendshipAddForm; 7 | import me.xiezefan.easyim.net.vo.DefaultResponseVo; 8 | import me.xiezefan.easyim.net.vo.UserVo; 9 | import retrofit.http.Body; 10 | import retrofit.http.DELETE; 11 | import retrofit.http.GET; 12 | import retrofit.http.POST; 13 | import retrofit.http.Path; 14 | import rx.Observable; 15 | 16 | 17 | /** 18 | * FriendShip Resource 19 | * Created by XieZeFan on 2015/4/12 0012. 20 | */ 21 | public interface FriendshipResource { 22 | 23 | @POST("/friends") 24 | public Observable save(@Body FriendshipAddForm dataForm); 25 | 26 | @DELETE("/friends/{id}") 27 | public Observable delete(@Path("id") String id); 28 | 29 | @GET("/friends") 30 | public Observable> list(); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/MessageResource.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net; 2 | 3 | import java.util.List; 4 | 5 | import me.xiezefan.easyim.net.from.MessageSendForm; 6 | import me.xiezefan.easyim.net.from.MessageStatusUpdateForm; 7 | import me.xiezefan.easyim.net.vo.DefaultResponseVo; 8 | import me.xiezefan.easyim.net.vo.MessageVo; 9 | import retrofit.http.Body; 10 | import retrofit.http.GET; 11 | import retrofit.http.POST; 12 | import retrofit.http.PUT; 13 | import retrofit.http.Part; 14 | import rx.Observable; 15 | 16 | /** 17 | * Message Resource 18 | * Created by XieZeFan on 2015/4/12 0012. 19 | */ 20 | public interface MessageResource { 21 | 22 | @POST("/messages/send") 23 | public Observable send(@Body MessageSendForm dataForm); 24 | 25 | @GET("/messages/offline") 26 | public Observable> getOffline(); 27 | 28 | @PUT("/messages") 29 | public Observable updateStatusBatch(@Body List dataForms); 30 | 31 | @PUT("/messages/{id}") 32 | public Observable updateStatus(@Part("id") String id, @Body MessageStatusUpdateForm dataForm); 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/RequestManager.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net; 2 | 3 | import retrofit.RestAdapter; 4 | 5 | /** 6 | * Http Request Manager 7 | * Created by XieZeFan on 2015/4/12 0012. 8 | */ 9 | public class RequestManager { 10 | // private static final String EASY_IM_ENDPOINT = "http://192.168.0.3:8080/EasyIM-Server/"; 11 | private static final String EASY_IM_ENDPOINT = "http://112.124.51.227:8080/easyim/"; 12 | 13 | private RestAdapter easyImRestAdapter; 14 | private UserResource userResource; 15 | private FriendshipResource friendshipResource; 16 | private MessageResource messageResource; 17 | 18 | /*----Getter----*/ 19 | public UserResource getUserResource() { 20 | return userResource; 21 | } 22 | 23 | public FriendshipResource getFriendshipResource() { 24 | return friendshipResource; 25 | } 26 | 27 | public MessageResource getMessageResource() { 28 | return messageResource; 29 | } 30 | 31 | 32 | 33 | private static RequestManager instance; 34 | public static RequestManager getInstance() { 35 | if (instance == null) { 36 | instance = new RequestManager(); 37 | instance.easyImRestAdapter = new RestAdapter.Builder() 38 | .setEndpoint(EASY_IM_ENDPOINT) 39 | .setRequestInterceptor(new AuthorizationRequestInterceptor()) 40 | .setErrorHandler(new DefaultErrorHandler()) 41 | .build(); 42 | instance.userResource = instance.easyImRestAdapter.create(UserResource.class); 43 | instance.friendshipResource = instance.easyImRestAdapter.create(FriendshipResource.class); 44 | instance.messageResource = instance.easyImRestAdapter.create(MessageResource.class); 45 | } 46 | return instance; 47 | } 48 | private RequestManager() {} 49 | 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/UploadTokenResource.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net; 2 | 3 | import me.xiezefan.easyim.net.vo.UploadTokenVo; 4 | import retrofit.http.GET; 5 | import rx.Observable; 6 | 7 | /** 8 | * 获取七牛云上传token 9 | * Created by xiezefan on 15/5/20. 10 | */ 11 | public interface UploadTokenResource { 12 | @GET("/tokens/generate") 13 | public Observable getToken(); 14 | 15 | } -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/UserResource.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net; 2 | 3 | 4 | import java.util.List; 5 | 6 | import me.xiezefan.easyim.net.from.LoginForm; 7 | import me.xiezefan.easyim.net.from.RegisterForm; 8 | import me.xiezefan.easyim.net.from.UserUpdateForm; 9 | import me.xiezefan.easyim.net.vo.DefaultResponseVo; 10 | import me.xiezefan.easyim.net.vo.UserVo; 11 | import retrofit.http.Body; 12 | import retrofit.http.GET; 13 | import retrofit.http.POST; 14 | import retrofit.http.PUT; 15 | import retrofit.http.Path; 16 | import retrofit.http.Query; 17 | import rx.Observable; 18 | 19 | /** 20 | * User Resource 21 | * Created by XieZeFan on 2015/4/12 0012. 22 | */ 23 | public interface UserResource { 24 | 25 | @POST("/users/register") 26 | public Observable register(@Body RegisterForm dataForm); 27 | 28 | @POST("/users/login") 29 | public Observable login(@Body LoginForm dataForm); 30 | 31 | @GET("/users/search") 32 | public Observable> search(@Query("q")String searchText); 33 | 34 | @GET("/users") 35 | public Observable> list(@Query("start")int start, @Query("row")int row); 36 | 37 | @GET("/users/{user_id}") 38 | public Observable getUserInfo(@Path("user_id")String userId); 39 | 40 | @PUT("/users/self") 41 | public Observable update(@Body UserUpdateForm dataForm); 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/from/FriendshipAddForm.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net.from; 2 | 3 | /** 4 | * Friendship Add Form 5 | * Created by XieZeFan on 2015/4/12 0012. 6 | */ 7 | public class FriendshipAddForm { 8 | public String friend_id; 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/from/LoginForm.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net.from; 2 | 3 | /** 4 | * User Login Form 5 | * Created by XieZeFan on 2015/4/12 0012. 6 | */ 7 | public class LoginForm { 8 | public String device_id; 9 | public String username; 10 | public String password; 11 | 12 | public LoginForm(String device_id, String username, String password) { 13 | this.device_id = device_id; 14 | this.username = username; 15 | this.password = password; 16 | } 17 | 18 | public LoginForm() { 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/from/MessageSendForm.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net.from; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Message Send Form 7 | * Created by XieZeFan on 2015/4/12 0012. 8 | */ 9 | public class MessageSendForm { 10 | private String to; 11 | private String type; 12 | private Map content; 13 | 14 | public String getTo() { 15 | return to; 16 | } 17 | 18 | public void setTo(String to) { 19 | this.to = to; 20 | } 21 | 22 | public String getType() { 23 | return type; 24 | } 25 | 26 | public void setType(String type) { 27 | this.type = type; 28 | } 29 | 30 | public Map getContent() { 31 | return content; 32 | } 33 | 34 | public void setContent(Map content) { 35 | this.content = content; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/from/MessageStatusUpdateForm.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net.from; 2 | 3 | /** 4 | * Created by XieZeFan on 2015/4/12 0012. 5 | */ 6 | public class MessageStatusUpdateForm { 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/from/RegisterForm.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net.from; 2 | 3 | /** 4 | * User Register Form 5 | * Created by XieZeFan on 2015/4/12 0012. 6 | */ 7 | public class RegisterForm { 8 | public String username; 9 | public String password; 10 | 11 | public RegisterForm() { 12 | } 13 | 14 | public RegisterForm(String username, String password) { 15 | this.username = username; 16 | this.password = password; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/from/UserUpdateForm.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net.from; 2 | 3 | public class UserUpdateForm { 4 | public String nickname; 5 | public String avatar; 6 | public String sex; 7 | public String description; 8 | public String location; 9 | 10 | public UserUpdateForm(String key, String value) { 11 | if ("nickname".equals(key)) { 12 | this.nickname = value; 13 | } else if ("avatar".equals(key)) { 14 | this.avatar = value; 15 | } else if ("sex".equals(key)) { 16 | this.sex = value; 17 | } else if ("description".equals(key)) { 18 | this.description = value; 19 | } else if ("location".equals(key)) { 20 | this.location = value; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/vo/DefaultResponseVo.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net.vo; 2 | 3 | /** 4 | * Default Response Vo 5 | * Created by XieZeFan on 2015/4/12 0012. 6 | */ 7 | public class DefaultResponseVo { 8 | public int code; 9 | public String message; 10 | 11 | public DefaultResponseVo() { 12 | } 13 | 14 | public DefaultResponseVo(int code, String message) { 15 | this.code = code; 16 | this.message = message; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/vo/MessageVo.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net.vo; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | * Created by XieZeFan on 2015/4/12 0012. 9 | */ 10 | public class MessageVo { 11 | public String id; 12 | public String type; 13 | public Map content; 14 | public Long create_time = -1L; 15 | 16 | public boolean validate() { 17 | return !TextUtils.isEmpty(id) 18 | && !TextUtils.isEmpty(type) 19 | && content != null 20 | && create_time != -1L; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/vo/RequestFailError.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net.vo; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.orhanobut.logger.Logger; 6 | 7 | import java.io.IOException; 8 | 9 | import me.xiezefan.easyim.util.JsonUtil; 10 | import me.xiezefan.easyim.util.StringUtil; 11 | import retrofit.RetrofitError; 12 | import retrofit.client.Response; 13 | 14 | /** 15 | * Http Request Fail Error 16 | * Created by XieZeFan on 2015/4/12 0012. 17 | */ 18 | public class RequestFailError extends Throwable { 19 | private DefaultResponseVo response; 20 | private RetrofitError error; 21 | 22 | public RequestFailError(RetrofitError cause) { 23 | super(cause); 24 | this.error = cause; 25 | Response _response = cause.getResponse(); 26 | try { 27 | String jsonStr = StringUtil.formatInputStream(_response.getBody().in()); 28 | if (!TextUtils.isEmpty(jsonStr)) { 29 | response = JsonUtil.format(jsonStr, DefaultResponseVo.class); 30 | return; 31 | } 32 | } catch (IOException e) { 33 | e.printStackTrace(); 34 | } 35 | response = new DefaultResponseVo(1000, "Bad Server"); 36 | // print error log 37 | Logger.e(String.format("Request %s Fail, Code:%s, Message:%s", cause.getUrl(), response.code, response.message)); 38 | } 39 | 40 | 41 | public DefaultResponseVo getResponse() { 42 | return response; 43 | } 44 | 45 | public void setResponse(DefaultResponseVo response) { 46 | this.response = response; 47 | } 48 | 49 | public RetrofitError getError() { 50 | return error; 51 | } 52 | 53 | public void setError(RetrofitError error) { 54 | this.error = error; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/vo/UploadTokenVo.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net.vo; 2 | 3 | /** 4 | * Created by xiezefan on 15/5/20. 5 | */ 6 | public class UploadTokenVo { 7 | public String token; 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/net/vo/UserVo.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.net.vo; 2 | 3 | import me.xiezefan.easyim.dao.Friend; 4 | 5 | /** 6 | * User View Model 7 | * Created by XieZeFan on 2015/4/12 0012. 8 | */ 9 | public class UserVo { 10 | public String id; 11 | public String username; 12 | public String nickname; 13 | public String avatar; 14 | public String description; 15 | public String location; 16 | public String sex; 17 | 18 | 19 | public Friend generateFriend() { 20 | Friend friend = new Friend(); 21 | friend.setUid(this.id); 22 | friend.setUsername(this.username); 23 | friend.setNickname(this.nickname); 24 | friend.setAvatar(this.avatar); 25 | friend.setDescription(this.description); 26 | friend.setSex(this.sex); 27 | friend.setLocation(this.location); 28 | return friend; 29 | } 30 | 31 | public Friend fixFriend(Friend friend) { 32 | friend.setUsername(this.username); 33 | friend.setNickname(this.nickname); 34 | friend.setAvatar(this.avatar); 35 | friend.setDescription(this.description); 36 | friend.setSex(this.sex); 37 | friend.setLocation(this.location); 38 | return friend; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/service/FriendshipService.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.service; 2 | 3 | import android.text.TextUtils; 4 | 5 | import javax.inject.Inject; 6 | 7 | import me.xiezefan.easyim.Application; 8 | import me.xiezefan.easyim.dao.Friend; 9 | import me.xiezefan.easyim.dao.FriendDao; 10 | import me.xiezefan.easyim.dao.FriendRequest; 11 | import me.xiezefan.easyim.dao.FriendRequestDao; 12 | import me.xiezefan.easyim.model.FriendRequestStatus; 13 | import me.xiezefan.easyim.net.FriendshipResource; 14 | import me.xiezefan.easyim.net.RequestManager; 15 | import me.xiezefan.easyim.net.from.FriendshipAddForm; 16 | import rx.Observable; 17 | import rx.Scheduler; 18 | import rx.android.schedulers.AndroidSchedulers; 19 | import rx.schedulers.Schedulers; 20 | 21 | /** 22 | * Created by XieZeFan on 2015/4/17 0017. 23 | */ 24 | public class FriendshipService { 25 | @Inject 26 | FriendshipResource friendshipResource; 27 | @Inject 28 | FriendDao friendDao; 29 | @Inject 30 | FriendRequestDao friendRequestDao; 31 | 32 | public void synchronizationRemote() { 33 | friendshipResource.list() 34 | .observeOn(Schedulers.io()) 35 | .subscribeOn(Schedulers.io()) 36 | .flatMap(list -> Observable.from(list)) 37 | .subscribe(friendVo -> { 38 | Friend friend = friendDao.queryBuilder().where(FriendDao.Properties.Uid.eq(friendVo.id)).unique(); 39 | if (friend == null) { 40 | friend = new Friend(); 41 | friend.setUid(friendVo.id); 42 | friend.setUsername(friendVo.username); 43 | friend.setNickname(friendVo.nickname); 44 | friend.setAvatar(friendVo.avatar); 45 | } else { 46 | friend.setUsername(friendVo.username); 47 | friend.setNickname(friendVo.nickname); 48 | friend.setAvatar(friendVo.avatar); 49 | } 50 | friendDao.insertOrReplace(friend); 51 | }); 52 | } 53 | 54 | public void addFriend(final FriendRequest friendRequest) { 55 | FriendshipAddForm dataForm = new FriendshipAddForm(); 56 | dataForm.friend_id = friendRequest.getUid(); 57 | 58 | friendshipResource.save(dataForm) 59 | .subscribeOn(Schedulers.io()) 60 | .observeOn(Schedulers.io()) 61 | .subscribe(response -> { 62 | // TODO show add friend Tip 63 | 64 | Friend friend = new Friend(); 65 | friend.setUid(friendRequest.getUid()); 66 | friend.setUsername(friendRequest.getUsername()); 67 | friend.setNickname(TextUtils.isEmpty(friendRequest.getNickname()) ? friendRequest.getDisplayName() : friendRequest.getNickname()); 68 | friend.setAvatar(friendRequest.getAvatar()); 69 | friendDao.insert(friend); 70 | 71 | }, error -> { 72 | // TODO show error info 73 | }); 74 | 75 | 76 | // update friendRequest 77 | friendRequest.setStatus(FriendRequestStatus.ACCEPT.name()); 78 | friendRequestDao.update(friendRequest); 79 | } 80 | 81 | 82 | 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/util/BitmapUtil.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.util; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapFactory; 5 | import android.os.Environment; 6 | 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.File; 9 | import java.io.FileOutputStream; 10 | import java.io.IOException; 11 | import java.nio.BufferUnderflowException; 12 | import java.nio.ByteBuffer; 13 | 14 | /** 15 | * Bitmap Util 16 | * Created by xiezefan on 15/5/21. 17 | */ 18 | public class BitmapUtil { 19 | 20 | public static byte[] bitmap2bytes(Bitmap bitmap) { 21 | int size = bitmap.getRowBytes() * bitmap.getHeight(); 22 | ByteBuffer b = ByteBuffer.allocate(size); 23 | 24 | bitmap.copyPixelsToBuffer(b); 25 | 26 | byte[] bytes = new byte[size]; 27 | 28 | try { 29 | b.get(bytes, 0, bytes.length); 30 | } catch (BufferUnderflowException e) { 31 | // always happens 32 | } 33 | return bytes; 34 | } 35 | 36 | public static File saveToFile(Bitmap bitmap, String filePath, String fileName) throws IOException { 37 | String file_path = Environment.getExternalStorageDirectory().getAbsolutePath() + filePath; 38 | File dir = new File(file_path); 39 | if(!dir.exists()) { 40 | dir.mkdirs(); 41 | } 42 | File file = new File(dir, fileName); 43 | FileOutputStream fOut = new FileOutputStream(file); 44 | 45 | bitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut); 46 | fOut.flush(); 47 | fOut.close(); 48 | return file; 49 | } 50 | 51 | public static Bitmap compressBySize(Bitmap bitmap, int targetWidth, int targetHeight) { 52 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 53 | bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); 54 | BitmapFactory.Options opts = new BitmapFactory.Options(); 55 | opts.inJustDecodeBounds = true; 56 | bitmap = BitmapFactory.decodeByteArray(baos.toByteArray(), 0, 57 | baos.toByteArray().length, opts); 58 | // 得到图片的宽度、高度; 59 | int imgWidth = opts.outWidth; 60 | int imgHeight = opts.outHeight; 61 | // 分别计算图片宽度、高度与目标宽度、高度的比例;取大于该比例的最小整数; 62 | int widthRatio = (int) Math.ceil(imgWidth / (float) targetWidth); 63 | int heightRatio = (int) Math.ceil(imgHeight / (float) targetHeight); 64 | if (widthRatio > 1 || heightRatio > 1) { 65 | if (widthRatio > heightRatio) { 66 | opts.inSampleSize = widthRatio; 67 | } else { 68 | opts.inSampleSize = heightRatio; 69 | } 70 | } 71 | // 设置好缩放比例后,加载图片进内存; 72 | opts.inJustDecodeBounds = false; 73 | Bitmap compressedBitmap = BitmapFactory.decodeByteArray( 74 | baos.toByteArray(), 0, baos.toByteArray().length, opts); 75 | recycleBitmap(bitmap); 76 | return compressedBitmap; 77 | } 78 | 79 | /** 80 | * 回收位图对象 81 | * 82 | * @param bitmap 83 | */ 84 | public static void recycleBitmap(Bitmap bitmap) { 85 | if (bitmap != null && !bitmap.isRecycled()) { 86 | bitmap.recycle(); 87 | System.gc(); 88 | bitmap = null; 89 | } 90 | } 91 | 92 | 93 | 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/util/CollectionUtil.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.util; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * Created by XieZeFan on 2015/3/22 0022. 8 | */ 9 | public class CollectionUtil { 10 | public static MapBuilder map() { 11 | return new MapBuilder(); 12 | } 13 | 14 | 15 | public static class MapBuilder { 16 | private Map map; 17 | 18 | public MapBuilder() { 19 | this.map = new HashMap<>(); 20 | } 21 | 22 | public MapBuilder put(String key, Object value) { 23 | map.put(key, value); 24 | return this; 25 | } 26 | 27 | public Map build() { 28 | return map; 29 | } 30 | } 31 | 32 | private CollectionUtil() {} 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/util/CommonUtil.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.util; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.graphics.Point; 6 | import android.util.TypedValue; 7 | import android.view.WindowManager; 8 | 9 | /** 10 | * Created by xiezefan-pc on 15-3-4. 11 | */ 12 | public class CommonUtil { 13 | 14 | 15 | public static int getScreenHeight(Context context) { 16 | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 17 | // Display.getWidth()已经被废弃, 以下的建议的获取屏幕宽度的方法 18 | Point point = new Point(); 19 | wm.getDefaultDisplay().getSize(point); 20 | return point.y; 21 | } 22 | 23 | public static int getScreenWidth(Context context) { 24 | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 25 | // Display.getWidth()已经被废弃, 以下的建议的获取屏幕宽度的方法 26 | Point point = new Point(); 27 | wm.getDefaultDisplay().getSize(point); 28 | return point.x; 29 | } 30 | 31 | public static int dpToPx(int dp) { 32 | return (int) (dp * Resources.getSystem().getDisplayMetrics().density); 33 | } 34 | 35 | private CommonUtil() {} 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/util/DateUtil.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.util; 2 | 3 | /** 4 | * Created by XieZeFan on 2015/4/25 0025. 5 | */ 6 | public class DateUtil { 7 | 8 | public static long getCurrentTimestamp() { 9 | return System.currentTimeMillis() / 1000; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/util/DisplayUtil.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.util; 2 | 3 | import android.content.Context; 4 | 5 | /** 6 | * Created by xiezefan-pc on 15-3-17. 7 | */ 8 | public class DisplayUtil { 9 | 10 | public static int px2dip(Context context, float pxValue) { 11 | final float scale = context.getResources().getDisplayMetrics().density; 12 | return (int) (pxValue / scale + 0.5f); 13 | } 14 | 15 | 16 | public static int dip2px(Context context, float dipValue) { 17 | final float scale = context.getResources().getDisplayMetrics().density; 18 | return (int) (dipValue * scale + 0.5f); 19 | } 20 | 21 | 22 | public static int px2sp(Context context, float pxValue) { 23 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 24 | return (int) (pxValue / fontScale + 0.5f); 25 | } 26 | 27 | 28 | public static int sp2px(Context context, float spValue) { 29 | final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; 30 | return (int) (spValue * fontScale + 0.5f); 31 | } 32 | 33 | public static int sp2dp(Context context, float spValue) { 34 | int px = sp2px(context, spValue); 35 | return px2dip(context, px); 36 | } 37 | 38 | public static int dp2sp(Context context, float dpValue) { 39 | return px2sp(context, dip2px(context, dpValue)); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/util/JsonUtil.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.util; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import com.google.gson.JsonSyntaxException; 6 | import com.google.gson.reflect.TypeToken; 7 | import com.google.gson.stream.JsonReader; 8 | 9 | import java.io.IOException; 10 | import java.io.StringReader; 11 | import java.util.ArrayList; 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | import java.util.Set; 16 | 17 | /** 18 | * Json Util By Gosn 19 | * Created by XieZeFan on 2015/4/12 0012. 20 | */ 21 | public final class JsonUtil { 22 | private static Gson gson = new Gson(); 23 | private static GsonBuilder gsonBuilder = new GsonBuilder(); 24 | 25 | public static Gson getGson() { 26 | return gson; 27 | } 28 | 29 | public static T format(String data, Class cls) { 30 | if (StringUtil.isEmpty(data)) { 31 | throw new JsonSyntaxException("Invalid JSON string."); 32 | } 33 | return gson.fromJson(data, cls); 34 | } 35 | 36 | public static List formatToList(String data, Class cls) { 37 | return gson.fromJson(data, new TypeToken>() {}.getType()); 38 | } 39 | 40 | public static Set formatToSet(String data, Class cls) { 41 | return gson.fromJson(data, new TypeToken>() {}.getType()); 42 | } 43 | 44 | public static List formatToList(String data) { 45 | return gson.fromJson(data, new TypeToken>() {}.getType()); 46 | } 47 | 48 | 49 | public static Map formatToMap(String data) throws JsonSyntaxException { 50 | GsonBuilder gb = new GsonBuilder(); 51 | Gson g = gb.create(); 52 | Map map = g.fromJson(data, new TypeToken>() {}.getType()); 53 | return map; 54 | } 55 | 56 | public static List> formatToArrayMap(String data) throws IOException { 57 | List> result = new ArrayList>(); 58 | JsonReader reader = null; 59 | reader = new JsonReader(new StringReader(data)); 60 | reader.setLenient(true); 61 | reader.beginArray(); 62 | while(reader.hasNext()) { 63 | reader.beginObject(); 64 | Map mapObj = new HashMap(); 65 | while (reader.hasNext()) { 66 | mapObj.put(reader.nextName(), reader.nextString()); 67 | } 68 | result.add(mapObj); 69 | reader.endObject(); 70 | } 71 | reader.endArray(); 72 | return result; 73 | } 74 | 75 | 76 | public static String toJson(Object data) { 77 | return JsonUtil.gson.toJson(data); 78 | } 79 | 80 | public static JsonBuilder newBuilder() { 81 | return new JsonBuilder(); 82 | } 83 | 84 | public static class JsonBuilder { 85 | Map data = new HashMap(); 86 | 87 | public JsonBuilder addItem(String key, Object value) { 88 | data.put(key, value); 89 | return this; 90 | } 91 | 92 | public String build() { 93 | return JsonUtil.toJson(data); 94 | } 95 | } 96 | 97 | 98 | 99 | private JsonUtil() {} 100 | 101 | 102 | 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/me/xiezefan/easyim/widget/ResizeRecyclerView.java: -------------------------------------------------------------------------------- 1 | package me.xiezefan.easyim.widget; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.util.AttributeSet; 7 | 8 | /** 9 | * Handler Resize Event RecyclerView 10 | * Created by xiezefan on 15/5/16. 11 | */ 12 | public class ResizeRecyclerView extends RecyclerView { 13 | private ResizeListener resizeListener; 14 | 15 | public ResizeRecyclerView(Context context) { 16 | super(context); 17 | } 18 | 19 | public ResizeRecyclerView(Context context, @Nullable AttributeSet attrs) { 20 | super(context, attrs); 21 | } 22 | 23 | public ResizeRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { 24 | super(context, attrs, defStyle); 25 | } 26 | 27 | 28 | @Override 29 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { 30 | super.onSizeChanged(w, h, oldw, oldh); 31 | if (resizeListener != null) { 32 | resizeListener.onResize(w, h, oldw, oldh); 33 | } 34 | } 35 | 36 | public void setResizeListener(ResizeListener resizeListener) { 37 | this.resizeListener = resizeListener; 38 | } 39 | 40 | public interface ResizeListener { 41 | public void onResize(int w, int h, int oldw, int oldh); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/res/anim/default_rotating.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-hdpi/ic_action_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_action_cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-hdpi/ic_action_cancel.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_action_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-hdpi/ic_action_search.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_action_storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-hdpi/ic_action_storage.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-mdpi/ic_action_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_action_cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-mdpi/ic_action_cancel.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_action_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-mdpi/ic_action_search.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_action_storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-mdpi/ic_action_storage.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/bg_default_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/bg_chat_item_left.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xhdpi/bg_chat_item_left.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/bg_chat_item_right.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xhdpi/bg_chat_item_right.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/bg_edit_text.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xhdpi/bg_edit_text.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/default_user_profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xhdpi/default_user_profile.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xhdpi/ic_action_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_action_cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xhdpi/ic_action_cancel.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_action_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xhdpi/ic_action_search.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_action_storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xhdpi/ic_action_storage.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xhdpi/ic_camera.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xhdpi/ic_loading.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_action_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xxhdpi/ic_action_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_action_cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xxhdpi/ic_action_cancel.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_action_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xxhdpi/ic_action_search.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_action_storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xxhdpi/ic_action_storage.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_chat_notification.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_default_gallery.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_default_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_friend_add_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_left_menu_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_login_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_register_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_send_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_warming_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/temp_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiezefan/EasyIM-Android/a271fa3323682b06ea8b1bce5c96a5fa872e4ece/app/src/main/res/drawable/temp_image.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_chat.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 10 | 18 | 24 | 25 | 39 | 52 | 53 | 54 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_contact.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 32 | 33 | 39 | 40 | 41 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_friend_add.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 28 | 29 |