└── NewIM
├── .idea
├── .name
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── vcs.xml
├── modules.xml
├── runConfigurations.xml
├── compiler.xml
├── gradle.xml
└── misc.xml
├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── on.png
│ │ │ │ ├── head.png
│ │ │ │ ├── off.png
│ │ │ │ ├── icon_geo.png
│ │ │ │ ├── icon_near.png
│ │ │ │ ├── login_bg.png
│ │ │ │ ├── msg_tips.png
│ │ │ │ ├── chat_send_n.png
│ │ │ │ ├── chat_send_p.png
│ │ │ │ ├── default_head.png
│ │ │ │ ├── ic_launcher.png
│ │ │ │ ├── login_logo.png
│ │ │ │ ├── voice_left.png
│ │ │ │ ├── voice_left1.png
│ │ │ │ ├── voice_left2.png
│ │ │ │ ├── voice_left3.png
│ │ │ │ ├── voice_right.png
│ │ │ │ ├── voice_right1.png
│ │ │ │ ├── voice_right2.png
│ │ │ │ ├── voice_right3.png
│ │ │ │ ├── chat_add_press.png
│ │ │ │ ├── chat_emo_press.png
│ │ │ │ ├── icon_set_press.png
│ │ │ │ ├── refresh_black.png
│ │ │ │ ├── chat_add_normal.png
│ │ │ │ ├── chat_emo_normal.png
│ │ │ │ ├── chat_icon_voice1.png
│ │ │ │ ├── chat_icon_voice2.png
│ │ │ │ ├── chat_icon_voice3.png
│ │ │ │ ├── chat_icon_voice4.png
│ │ │ │ ├── chat_icon_voice5.png
│ │ │ │ ├── chat_icon_voice6.png
│ │ │ │ ├── chat_voice_normal.png
│ │ │ │ ├── chat_voice_press.png
│ │ │ │ ├── icon_msg_search.png
│ │ │ │ ├── icon_set_normal.png
│ │ │ │ ├── new_friends_icon.png
│ │ │ │ ├── chat_keyboard_press.png
│ │ │ │ ├── icon_contact_normal.png
│ │ │ │ ├── icon_contact_press.png
│ │ │ │ ├── icon_message_normal.png
│ │ │ │ ├── icon_message_press.png
│ │ │ │ ├── login_icon_account.png
│ │ │ │ ├── login_icon_password.png
│ │ │ │ ├── base_horization_line.png
│ │ │ │ ├── chat_add_camera_normal.png
│ │ │ │ ├── chat_add_camera_press.png
│ │ │ │ ├── chat_add_picture_press.png
│ │ │ │ ├── chat_fail_resend_press.png
│ │ │ │ ├── chat_icon_voice_short.png
│ │ │ │ ├── chat_keyboard_normal.png
│ │ │ │ ├── register_bottom_arrow.png
│ │ │ │ ├── base_action_bar_add_bg_n.png
│ │ │ │ ├── base_action_bar_add_bg_p.png
│ │ │ │ ├── chat_add_location_normal.png
│ │ │ │ ├── chat_add_location_press.png
│ │ │ │ ├── chat_add_picture_normal.png
│ │ │ │ ├── chat_fail_resend_normal.png
│ │ │ │ ├── base_action_bar_back_bg_n.png
│ │ │ │ ├── base_action_bar_back_bg_p.png
│ │ │ │ ├── base_action_bar_more_bg_n.png
│ │ │ │ ├── base_action_bar_more_bg_p.png
│ │ │ │ ├── base_action_bar_true_bg_n.png
│ │ │ │ └── base_action_bar_true_bg_p.png
│ │ │ ├── drawable
│ │ │ │ ├── input_bg.9.png
│ │ │ │ ├── pop_bg.9.png
│ │ │ │ ├── top_bar.9.png
│ │ │ │ ├── about_mid_bg.9.png
│ │ │ │ ├── about_top_bg.9.png
│ │ │ │ ├── btn_login_n.9.png
│ │ │ │ ├── btn_login_p.9.png
│ │ │ │ ├── btn_logout_n.9.png
│ │ │ │ ├── btn_logout_p.9.png
│ │ │ │ ├── chat_left_qp.9.png
│ │ │ │ ├── chat_right_qp.9.png
│ │ │ │ ├── chat_voice_bg.9.png
│ │ │ │ ├── pop_bg_press.9.png
│ │ │ │ ├── about_bottom_bg.9.png
│ │ │ │ ├── base_dialog_bg.9.png
│ │ │ │ ├── chat_top_voice_bg.9.png
│ │ │ │ ├── list_newmessage2.9.png
│ │ │ │ ├── location_default.9.png
│ │ │ │ ├── base_comment_emo_bar.9.png
│ │ │ │ ├── base_horizontal_line.9.png
│ │ │ │ ├── chat_voice_bg_press.9.png
│ │ │ │ ├── list_conversation_press.9.png
│ │ │ │ ├── base_horizontal_line_red.9.png
│ │ │ │ ├── contact_list_buddy_item_bg.9.png
│ │ │ │ ├── tab_set_btn.xml
│ │ │ │ ├── drawable_edit_normal.xml
│ │ │ │ ├── tab_contact_btn.xml
│ │ │ │ ├── tab_message_btn.xml
│ │ │ │ ├── btn_login_selector.xml
│ │ │ │ ├── btn_logout_selector.xml
│ │ │ │ ├── tab_textcolor.xml
│ │ │ │ ├── btn_selector.xml
│ │ │ │ ├── btn_chat_add_selector.xml
│ │ │ │ ├── btn_chat_emo_selector.xml
│ │ │ │ ├── btn_chat_send_selector.xml
│ │ │ │ ├── button_normal_shape.xml
│ │ │ │ ├── btn_chat_voice_selector.xml
│ │ │ │ ├── btn_chat_keyboard_selector.xml
│ │ │ │ ├── btn_chat_fail_resend.xml
│ │ │ │ ├── btn_chat_add_camera_selector.xml
│ │ │ │ ├── base_action_bar_add_bg_selector.xml
│ │ │ │ ├── btn_chat_add_location_selector.xml
│ │ │ │ ├── btn_chat_add_picture_selector.xml
│ │ │ │ ├── base_action_bar_more_bg_selector.xml
│ │ │ │ ├── base_action_bar_true_bg_selector.xml
│ │ │ │ ├── base_action_bar_back_bg_selector.xml
│ │ │ │ ├── btn_chat_record_selector.xml
│ │ │ │ ├── anim_chat_voice_right.xml
│ │ │ │ └── anim_chat_voice_left.xml
│ │ │ ├── mipmap-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── menu
│ │ │ │ └── menu_main.xml
│ │ │ ├── values-v21
│ │ │ │ └── styles.xml
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ ├── layout
│ │ │ │ ├── activity_splash.xml
│ │ │ │ ├── fragment_conversation.xml
│ │ │ │ ├── fragment_contact.xml
│ │ │ │ ├── include_pullrefresh.xml
│ │ │ │ ├── include_chat_voice_short.xml
│ │ │ │ ├── item_chat_agree.xml
│ │ │ │ ├── include_chat_add.xml
│ │ │ │ ├── item_search_user.xml
│ │ │ │ ├── activity_search_user.xml
│ │ │ │ ├── item_contact.xml
│ │ │ │ ├── activity_chat.xml
│ │ │ │ ├── include_navi.xml
│ │ │ │ ├── item_chat_received_message.xml
│ │ │ │ ├── header_new_friend.xml
│ │ │ │ ├── item_chat_received_image.xml
│ │ │ │ ├── item_chat_received_location.xml
│ │ │ │ ├── item_chat_received_voice.xml
│ │ │ │ ├── activity_register.xml
│ │ │ │ ├── item_chat_sent_image.xml
│ │ │ │ ├── item_new_friend.xml
│ │ │ │ ├── item_chat_sent_message.xml
│ │ │ │ ├── activity_user_info.xml
│ │ │ │ ├── item_chat_sent_location.xml
│ │ │ │ ├── item_conversation.xml
│ │ │ │ └── activity_login.xml
│ │ │ └── values
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ ├── java
│ │ │ └── cn
│ │ │ │ └── bmob
│ │ │ │ └── imdemo
│ │ │ │ ├── event
│ │ │ │ ├── RefreshEvent.java
│ │ │ │ └── FinishEvent.java
│ │ │ │ ├── adapter
│ │ │ │ ├── OnRecyclerViewListener.java
│ │ │ │ ├── base
│ │ │ │ │ ├── IMutlipleItem.java
│ │ │ │ │ ├── BaseViewHolder.java
│ │ │ │ │ └── BaseRecyclerHolder.java
│ │ │ │ ├── AgreeHolder.java
│ │ │ │ ├── SearchUserHolder.java
│ │ │ │ ├── ContactAdapter.java
│ │ │ │ ├── SearchUserAdapter.java
│ │ │ │ ├── ConversationAdapter.java
│ │ │ │ ├── ReceiveTextHolder.java
│ │ │ │ ├── ReceiveVideoHolder.java
│ │ │ │ ├── ReceiveLocationHolder.java
│ │ │ │ └── ReceiveImageHolder.java
│ │ │ │ ├── model
│ │ │ │ ├── i
│ │ │ │ │ ├── UpdateCacheListener.java
│ │ │ │ │ └── QueryUserListener.java
│ │ │ │ └── BaseModel.java
│ │ │ │ ├── base
│ │ │ │ ├── ImageLoaderFactory.java
│ │ │ │ ├── ILoader.java
│ │ │ │ ├── BaseFragment.java
│ │ │ │ └── UniversalImageLoader.java
│ │ │ │ ├── bean
│ │ │ │ ├── User.java
│ │ │ │ ├── Friend.java
│ │ │ │ ├── AddFriendMessage.java
│ │ │ │ ├── NewFriendConversation.java
│ │ │ │ ├── AgreeAddFriendMessage.java
│ │ │ │ ├── Conversation.java
│ │ │ │ └── PrivateConversation.java
│ │ │ │ ├── util
│ │ │ │ ├── Util.java
│ │ │ │ ├── LifecycleCallbacksAdapter.java
│ │ │ │ ├── DisplayConfig.java
│ │ │ │ └── TimeUtil.java
│ │ │ │ ├── Config.java
│ │ │ │ ├── ui
│ │ │ │ ├── SplashActivity.java
│ │ │ │ ├── RegisterActivity.java
│ │ │ │ ├── LoginActivity.java
│ │ │ │ ├── fragment
│ │ │ │ │ └── SetFragment.java
│ │ │ │ ├── SearchUserActivity.java
│ │ │ │ └── UserInfoActivity.java
│ │ │ │ ├── db
│ │ │ │ ├── dao
│ │ │ │ │ ├── DaoSession.java
│ │ │ │ │ └── DaoMaster.java
│ │ │ │ └── NewFriend.java
│ │ │ │ └── BmobIMApplication.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── cn
│ │ │ └── bmob
│ │ │ └── imdemo
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── cn
│ │ └── bmob
│ │ └── imdemo
│ │ └── ApplicationTest.java
├── libs
│ └── universal-image-loader-1.9.5.jar
└── build.gradle
├── settings.gradle
├── .gitignore
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitattributes
├── build.gradle
├── gradle.properties
├── NewIM.iml
└── gradlew.bat
/NewIM/.idea/.name:
--------------------------------------------------------------------------------
1 | NewIM
--------------------------------------------------------------------------------
/NewIM/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/NewIM/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/NewIM/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/NewIM/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /local.properties
3 | /.idea/workspace.xml
4 | /.idea/libraries
5 | .DS_Store
6 | /build
7 | /captures
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/on.png
--------------------------------------------------------------------------------
/NewIM/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/head.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/head.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/off.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/input_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/input_bg.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/pop_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/pop_bg.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/top_bar.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/top_bar.9.png
--------------------------------------------------------------------------------
/NewIM/app/libs/universal-image-loader-1.9.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/libs/universal-image-loader-1.9.5.jar
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/icon_geo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/icon_geo.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/icon_near.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/icon_near.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/login_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/login_bg.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/msg_tips.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/msg_tips.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/about_mid_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/about_mid_bg.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/about_top_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/about_top_bg.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_login_n.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/btn_login_n.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_login_p.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/btn_login_p.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_logout_n.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/btn_logout_n.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_logout_p.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/btn_logout_p.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/chat_left_qp.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/chat_left_qp.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/chat_right_qp.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/chat_right_qp.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/chat_voice_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/chat_voice_bg.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/pop_bg_press.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/pop_bg_press.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_send_n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_send_n.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_send_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_send_p.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/default_head.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/default_head.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/login_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/login_logo.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/voice_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/voice_left.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/voice_left1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/voice_left1.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/voice_left2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/voice_left2.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/voice_left3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/voice_left3.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/voice_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/voice_right.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/voice_right1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/voice_right1.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/voice_right2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/voice_right2.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/voice_right3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/voice_right3.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/about_bottom_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/about_bottom_bg.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/base_dialog_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/base_dialog_bg.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_add_press.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_add_press.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_emo_press.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_emo_press.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/icon_set_press.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/icon_set_press.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/refresh_black.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/refresh_black.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/chat_top_voice_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/chat_top_voice_bg.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/list_newmessage2.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/list_newmessage2.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/location_default.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/location_default.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_add_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_add_normal.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_emo_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_emo_normal.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice1.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice2.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice3.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice4.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice5.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice6.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_voice_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_voice_normal.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_voice_press.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_voice_press.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/icon_msg_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/icon_msg_search.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/icon_set_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/icon_set_normal.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/new_friends_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/new_friends_icon.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/base_comment_emo_bar.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/base_comment_emo_bar.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/base_horizontal_line.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/base_horizontal_line.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/chat_voice_bg_press.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/chat_voice_bg_press.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_keyboard_press.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_keyboard_press.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/icon_contact_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/icon_contact_normal.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/icon_contact_press.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/icon_contact_press.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/icon_message_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/icon_message_normal.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/icon_message_press.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/icon_message_press.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/login_icon_account.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/login_icon_account.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/login_icon_password.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/login_icon_password.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/list_conversation_press.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/list_conversation_press.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/base_horization_line.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/base_horization_line.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_add_camera_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_add_camera_normal.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_add_camera_press.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_add_camera_press.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_add_picture_press.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_add_picture_press.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_fail_resend_press.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_fail_resend_press.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice_short.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_icon_voice_short.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_keyboard_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_keyboard_normal.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/register_bottom_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/register_bottom_arrow.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/base_horizontal_line_red.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/base_horizontal_line_red.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_add_bg_n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_add_bg_n.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_add_bg_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_add_bg_p.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_add_location_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_add_location_normal.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_add_location_press.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_add_location_press.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_add_picture_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_add_picture_normal.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/chat_fail_resend_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/chat_fail_resend_normal.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/contact_list_buddy_item_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/drawable/contact_list_buddy_item_bg.9.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_back_bg_n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_back_bg_n.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_back_bg_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_back_bg_p.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_more_bg_n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_more_bg_n.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_more_bg_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_more_bg_p.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_true_bg_n.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_true_bg_n.png
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_true_bg_p.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bodismile/bmob-newim-demo/HEAD/NewIM/app/src/main/res/mipmap-hdpi/base_action_bar_true_bg_p.png
--------------------------------------------------------------------------------
/NewIM/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/NewIM/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/event/RefreshEvent.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.event;
2 |
3 | /**
4 | * Created by Administrator on 2016/4/28.
5 | */
6 | public class RefreshEvent {
7 | public RefreshEvent(){}
8 | }
9 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/event/FinishEvent.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.event;
2 |
3 | /**
4 | * @author :smile
5 | * @project:FinishEvent
6 | * @date :2016-01-25-15:25
7 | */
8 | public class FinishEvent {
9 |
10 | public FinishEvent(){}
11 | }
12 |
--------------------------------------------------------------------------------
/NewIM/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jan 15 11:36:31 CST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/tab_set_btn.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/drawable_edit_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/tab_contact_btn.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/tab_message_btn.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_login_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_logout_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/tab_textcolor.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/OnRecyclerViewListener.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter;
2 |
3 | /**为RecycleView添加点击事件
4 | * @author smile
5 | * @project OnRecyclerViewListener
6 | * @date 2016-03-03-16:39
7 | */
8 | public interface OnRecyclerViewListener {
9 | void onItemClick(int position);
10 | boolean onItemLongClick(int position);
11 | }
12 |
--------------------------------------------------------------------------------
/NewIM/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 | >
2 |
3 |
9 |
10 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_chat_add_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_chat_emo_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_chat_send_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/button_normal_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_chat_voice_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/test/java/cn/bmob/imdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_chat_keyboard_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_chat_fail_resend.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_chat_add_camera_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/base_action_bar_add_bg_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_chat_add_location_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_chat_add_picture_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/androidTest/java/cn/bmob/imdemo/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo;
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 | }
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/base_action_bar_more_bg_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/base_action_bar_true_bg_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/base_action_bar_back_bg_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NewIM/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/btn_chat_record_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/model/i/UpdateCacheListener.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.model.i;
2 |
3 | import cn.bmob.v3.exception.BmobException;
4 | import cn.bmob.v3.listener.BmobListener;
5 |
6 | /**
7 | * @author :smile
8 | * @project:UpdateCacheListener
9 | * @date :2016-02-01-16:23
10 | */
11 | public abstract class UpdateCacheListener extends BmobListener {
12 | public abstract void done(BmobException e);
13 |
14 | @Override
15 | protected void postDone(Object o, BmobException e) {
16 | done(e);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/model/BaseModel.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.model;
2 |
3 | import android.content.Context;
4 |
5 | import cn.bmob.imdemo.BmobIMApplication;
6 |
7 | /**
8 | * @author :smile
9 | * @project:BaseModel
10 | * @date :2016-01-23-10:37
11 | */
12 | public abstract class BaseModel {
13 |
14 | public int CODE_NULL=1000;
15 | public static int CODE_NOT_EQUAL=1001;
16 |
17 | public static final int DEFAULT_LIMIT=20;
18 |
19 | public Context getContext(){
20 | return BmobIMApplication.INSTANCE();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/model/i/QueryUserListener.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.model.i;
2 |
3 | import cn.bmob.imdemo.bean.User;
4 | import cn.bmob.v3.exception.BmobException;
5 | import cn.bmob.v3.listener.BmobListener;
6 |
7 | /**
8 | * @author :smile
9 | * @project:QueryUserListener
10 | * @date :2016-02-01-16:23
11 | */
12 | public abstract class QueryUserListener extends BmobListener {
13 |
14 | public abstract void done(User s, BmobException e);
15 |
16 | @Override
17 | protected void postDone(User o, BmobException e) {
18 | done(o, e);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/NewIM/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/anim_chat_voice_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
10 |
13 |
16 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/drawable/anim_chat_voice_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
10 |
13 |
16 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/base/ImageLoaderFactory.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.base;
2 |
3 | /**
4 | * Created by Administrator on 2016/5/24.
5 | */
6 | public class ImageLoaderFactory {
7 |
8 | private static volatile ILoader sInstance;
9 |
10 | private ImageLoaderFactory() {}
11 |
12 | public static ILoader getLoader() {
13 | if (sInstance == null) {
14 | synchronized (ImageLoaderFactory.class) {
15 | if (sInstance == null) {
16 | sInstance = new UniversalImageLoader();
17 | }
18 | }
19 | }
20 | return sInstance;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/base/IMutlipleItem.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter.base;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by Administrator on 2016/5/6.
7 | */
8 | public interface IMutlipleItem {
9 |
10 | /**
11 | * 多种布局的layout文件
12 | * @param viewtype
13 | * @return
14 | */
15 | int getItemLayoutId(int viewtype);
16 |
17 | /**
18 | * 多种布局类型
19 | * @param postion
20 | * @param t
21 | * @return
22 | */
23 | int getItemViewType(int postion, T t);
24 |
25 | /**
26 | * 返回布局个数
27 | * @param list
28 | * @return
29 | */
30 | int getItemCount(List list);
31 | }
32 |
--------------------------------------------------------------------------------
/NewIM/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.3.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | //Bmob的maven仓库地址,必须填写
19 | maven { url "https://raw.github.com/bmob/bmob-android-sdk/master" }
20 | }
21 | }
22 |
23 | task clean(type: Delete) {
24 | delete rootProject.buildDir
25 | }
26 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/bean/User.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.bean;
2 |
3 | import cn.bmob.imdemo.db.NewFriend;
4 | import cn.bmob.v3.BmobUser;
5 |
6 | /**
7 | * @author :smile
8 | * @project:User
9 | * @date :2016-01-22-18:11
10 | */
11 | public class User extends BmobUser {
12 |
13 | private String avatar;
14 |
15 | public User(){}
16 |
17 | public User(NewFriend friend){
18 | setObjectId(friend.getUid());
19 | setUsername(friend.getName());
20 | setAvatar(friend.getAvatar());
21 | }
22 |
23 | public String getAvatar() {
24 | return avatar;
25 | }
26 |
27 | public void setAvatar(String avatar) {
28 | this.avatar = avatar;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/base/ILoader.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.base;
2 |
3 | import android.widget.ImageView;
4 |
5 | import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
6 |
7 | /**
8 | * 抽象的图片加载接口
9 | * @author smile
10 | */
11 | public interface ILoader {
12 |
13 | /**
14 | * 加载圆形头像
15 | * @param iv
16 | * @param url
17 | * @param defaultRes
18 | */
19 | void loadAvator(ImageView iv, String url, int defaultRes);
20 |
21 | /**
22 | * 加载图片,添加监听器
23 | * @param iv
24 | * @param url
25 | * @param defaultRes
26 | * @param listener
27 | */
28 | void load(ImageView iv,String url,int defaultRes,ImageLoadingListener listener);
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/NewIM/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/util/Util.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.util;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 |
6 | import java.io.BufferedInputStream;
7 | import java.io.BufferedOutputStream;
8 | import java.io.ByteArrayOutputStream;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.io.OutputStream;
12 | import java.net.URL;
13 |
14 | /**
15 | * @author smile
16 | * @project Util
17 | * @date 2016-03-01-14:55
18 | */
19 | public class Util {
20 | public static boolean checkSdCard() {
21 | if (android.os.Environment.getExternalStorageState().equals(
22 | android.os.Environment.MEDIA_MOUNTED))
23 | return true;
24 | else
25 | return false;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/NewIM/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/bean/Friend.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.bean;
2 |
3 | import cn.bmob.v3.BmobObject;
4 |
5 | /**好友表
6 | * @author smile
7 | * @project Friend
8 | * @date 2016-04-26
9 | */
10 | public class Friend extends BmobObject{
11 |
12 | private User user;
13 | private User friendUser;
14 |
15 | //拼音
16 | private transient String pinyin;
17 |
18 | public String getPinyin() {
19 | return pinyin;
20 | }
21 |
22 | public void setPinyin(String pinyin) {
23 | this.pinyin = pinyin;
24 | }
25 |
26 | public User getUser() {
27 | return user;
28 | }
29 |
30 | public void setUser(User user) {
31 | this.user = user;
32 | }
33 |
34 | public User getFriendUser() {
35 | return friendUser;
36 | }
37 |
38 | public void setFriendUser(User friendUser) {
39 | this.friendUser = friendUser;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/Config.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo;
2 |
3 | /**
4 | * @author :smile
5 | * @project:Config
6 | * @date :2016-01-15-18:23
7 | */
8 | public class Config {
9 | /**
10 | * Bmob应用key
11 | */
12 | // public static final String DEFAULT_APPKEY="d6f44e8f1ba9d3dcf4fab7a487fa97dd";//内
13 | public static final String DEFAULT_APPKEY="87ab0f9bee41bce86dfadd69af692873";//外
14 | //是否是debug模式
15 | public static final boolean DEBUG=true;
16 | //好友请求:未读-未添加->接收到别人发给我的好友添加请求,初始状态
17 | public static final int STATUS_VERIFY_NONE=0;
18 | //好友请求:已读-未添加->点击查看了新朋友,则都变成已读状态
19 | public static final int STATUS_VERIFY_READED=2;
20 | //好友请求:已添加
21 | public static final int STATUS_VERIFIED=1;
22 | //好友请求:拒绝
23 | public static final int STATUS_VERIFY_REFUSE=3;
24 | //好友请求:我发出的好友请求-暂未存储到本地数据库中
25 | public static final int STATUS_VERIFY_ME_SEND=4;
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/fragment_conversation.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
16 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/fragment_contact.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
16 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/include_pullrefresh.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
16 |
17 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/NewIM/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | org.gradle.parallel=true
19 | org.gradle.daemon=true
--------------------------------------------------------------------------------
/NewIM/NewIM.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/util/LifecycleCallbacksAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.util;
2 |
3 | import android.app.Activity;
4 | import android.app.Application;
5 | import android.os.Bundle;
6 |
7 | /** Helper to avoid implementing all lifecycle callback methods. */
8 | public class LifecycleCallbacksAdapter implements Application.ActivityLifecycleCallbacks {
9 | @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
10 |
11 | }
12 |
13 | @Override public void onActivityStarted(Activity activity) {
14 |
15 | }
16 |
17 | @Override public void onActivityResumed(Activity activity) {
18 |
19 | }
20 |
21 | @Override public void onActivityPaused(Activity activity) {
22 |
23 | }
24 |
25 | @Override public void onActivityStopped(Activity activity) {
26 |
27 | }
28 |
29 | @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
30 |
31 | }
32 |
33 | @Override public void onActivityDestroyed(Activity activity) {
34 |
35 | }
36 | }
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/include_chat_voice_short.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
18 |
19 |
26 |
27 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/ui/SplashActivity.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.ui;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.os.Looper;
6 |
7 | import cn.bmob.imdemo.R;
8 | import cn.bmob.imdemo.bean.User;
9 | import cn.bmob.imdemo.base.BaseActivity;
10 | import cn.bmob.imdemo.model.UserModel;
11 |
12 | /**启动界面
13 | * @author :smile
14 | * @project:SplashActivity
15 | * @date :2016-01-15-18:23
16 | */
17 | public class SplashActivity extends BaseActivity {
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_splash);
23 | Handler handler =new Handler(Looper.getMainLooper());
24 | handler.postDelayed(new Runnable() {
25 | @Override
26 | public void run() {
27 | User user = UserModel.getInstance().getCurrentUser();
28 | if (user == null) {
29 | startActivity(LoginActivity.class,null,true);
30 | }else{
31 | startActivity(MainActivity.class,null,true);
32 | }
33 | }
34 | },1000);
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 16dp
6 | 48.0dip
7 |
8 | 13sp
9 | 10sp
10 | 14sp
11 | 16sp
12 | 18sp
13 |
14 | 2dip
15 | 1dip
16 | 40dip
17 | 50dip
18 | 75dp
19 | 70dp
20 |
21 | 3dp
22 | 5dp
23 | 8dp
24 | 10dp
25 | 11dp
26 | 12dp
27 | 16dp
28 | 15dp
29 | 18dp
30 | 30dp
31 | 40dp
32 |
33 |
34 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_chat_agree.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
31 |
32 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/AgreeHolder.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.TextView;
7 |
8 | import java.text.SimpleDateFormat;
9 |
10 | import butterknife.Bind;
11 | import cn.bmob.imdemo.R;
12 | import cn.bmob.imdemo.adapter.base.BaseViewHolder;
13 | import cn.bmob.newim.bean.BmobIMMessage;
14 |
15 | /**
16 | * 同意添加好友的agree类型
17 | */
18 | public class AgreeHolder extends BaseViewHolder implements View.OnClickListener,View.OnLongClickListener {
19 |
20 | @Bind(R.id.tv_time)
21 | protected TextView tv_time;
22 |
23 | @Bind(R.id.tv_message)
24 | protected TextView tv_message;
25 |
26 | public AgreeHolder(Context context, ViewGroup root, OnRecyclerViewListener listener) {
27 | super(context, root, R.layout.item_chat_agree, listener);
28 | }
29 |
30 | @Override
31 | public void bindData(Object o) {
32 | final BmobIMMessage message = (BmobIMMessage)o;
33 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
34 | String time = dateFormat.format(message.getCreateTime());
35 | String content = message.getContent();
36 | tv_message.setText(content);
37 | tv_time.setText(time);
38 | }
39 |
40 | public void showTime(boolean isShow) {
41 | tv_time.setVisibility(isShow ? View.VISIBLE : View.GONE);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/db/dao/DaoSession.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.db.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 cn.bmob.imdemo.db.NewFriend;
13 |
14 | import cn.bmob.imdemo.db.dao.NewFriendDao;
15 |
16 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
17 |
18 | /**
19 | * {@inheritDoc}
20 | *
21 | * @see de.greenrobot.dao.AbstractDaoSession
22 | */
23 | public class DaoSession extends AbstractDaoSession {
24 |
25 | private final DaoConfig newFriendDaoConfig;
26 |
27 | private final NewFriendDao newFriendDao;
28 |
29 | public DaoSession(SQLiteDatabase db, IdentityScopeType type, Map>, DaoConfig>
30 | daoConfigMap) {
31 | super(db);
32 |
33 | newFriendDaoConfig = daoConfigMap.get(NewFriendDao.class).clone();
34 | newFriendDaoConfig.initIdentityScope(type);
35 |
36 | newFriendDao = new NewFriendDao(newFriendDaoConfig, this);
37 |
38 | registerDao(NewFriend.class, newFriendDao);
39 | }
40 |
41 | public void clear() {
42 | newFriendDaoConfig.getIdentityScope().clear();
43 | }
44 |
45 | public NewFriendDao getNewFriendDao() {
46 | return newFriendDao;
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #00000000
7 |
8 | #3e3e39
9 | #9fa0a0
10 | #ffffff
11 | #489cfa
12 |
13 | #ffa1a1a1
14 | #272a2e
15 | #9da0a4
16 | #4f9ef6
17 | #969696
18 | #eceff4
19 |
20 | #f0f2f5
21 | #ed4e23
22 | #f4f6f6
23 | #f82c22
24 | #898989
25 |
26 | #fcfcfc
27 | #999999
28 | #dadada
29 | #818181
30 | #20000000
31 | #1e1e1e
32 | #b4b4b4
33 |
34 |
35 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/SearchUserHolder.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.Button;
8 | import android.widget.ImageView;
9 | import android.widget.TextView;
10 |
11 | import butterknife.Bind;
12 | import cn.bmob.imdemo.R;
13 | import cn.bmob.imdemo.adapter.base.BaseViewHolder;
14 | import cn.bmob.imdemo.base.ImageLoaderFactory;
15 | import cn.bmob.imdemo.bean.User;
16 | import cn.bmob.imdemo.ui.UserInfoActivity;
17 |
18 | public class SearchUserHolder extends BaseViewHolder {
19 |
20 | @Bind(R.id.avatar)
21 | public ImageView avatar;
22 | @Bind(R.id.name)
23 | public TextView name;
24 | @Bind(R.id.btn_add)
25 | public Button btn_add;
26 |
27 | public SearchUserHolder(Context context, ViewGroup root,OnRecyclerViewListener onRecyclerViewListener) {
28 | super(context, root, R.layout.item_search_user,onRecyclerViewListener);
29 | }
30 |
31 | @Override
32 | public void bindData(Object o) {
33 | final User user =(User)o;
34 | ImageLoaderFactory.getLoader().loadAvator(avatar,user.getAvatar(), R.mipmap.head);
35 | name.setText(user.getUsername());
36 | btn_add.setOnClickListener(new View.OnClickListener() {
37 | @Override
38 | public void onClick(View v) {//查看个人详情
39 | Bundle bundle = new Bundle();
40 | bundle.putSerializable("u", user);
41 | startActivity(UserInfoActivity.class,bundle);
42 | }
43 | });
44 | }
45 | }
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/include_chat_add.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
20 |
30 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/util/DisplayConfig.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.util;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | import com.nostra13.universalimageloader.core.DisplayImageOptions;
6 | import com.nostra13.universalimageloader.core.assist.ImageScaleType;
7 | import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
8 |
9 | /**
10 | * @author :smile
11 | * @project:DisplayConfig
12 | * @date :2016-01-25-09:19
13 | * 注:由于Picasso圆角处理不够完美,故舍弃
14 | */
15 | public class DisplayConfig {
16 |
17 | /**UIL默认的显示配置:圆角
18 | * @param defaultRes
19 | * @return
20 | */
21 | public static DisplayImageOptions getDefaultOptions(boolean hasRounded,int defaultRes){
22 | DisplayImageOptions.Builder builder = new DisplayImageOptions.Builder()
23 | .cacheInMemory(true)//设置下载的图片是否缓存在内存中
24 | .cacheOnDisc(true)//设置下载的图片是否缓存在SD卡中
25 | .considerExifParams(true) //是否考虑JPEG图像EXIF参数(旋转,翻转)
26 | .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)//设置图片以如何的编码方式显示
27 | .bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型:设置为RGB565比起默认的ARGB_8888要节省大量的内存
28 | // .delayBeforeLoading(100)//载入图片前稍做延时可以提高整体滑动的流畅度
29 | .resetViewBeforeLoading(true);//设置图片在下载前是否重置,复位
30 | if(hasRounded){
31 | builder.displayer(new RoundedBitmapDisplayer(12));//是否设置为圆角,弧度为多少
32 | }
33 | if(defaultRes!=0){
34 | builder.showImageForEmptyUri(defaultRes)//设置图片Uri为空或是错误的时候显示的图片
35 | // .showImageOnLoading(defaultRes) //设置图片在下载期间显示的图片-->应该去掉-会造成ListView中图片闪烁
36 | .showImageOnFail(defaultRes); //设置图片加载/解码过程中错误时候显示的图片
37 | }
38 | return builder.build();//构建完成
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_search_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
22 |
23 |
32 |
33 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/ContactAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 |
6 | import java.util.Collection;
7 |
8 | import cn.bmob.imdemo.R;
9 | import cn.bmob.imdemo.adapter.base.BaseRecyclerAdapter;
10 | import cn.bmob.imdemo.adapter.base.BaseRecyclerHolder;
11 | import cn.bmob.imdemo.adapter.base.IMutlipleItem;
12 | import cn.bmob.imdemo.bean.Friend;
13 | import cn.bmob.imdemo.bean.User;
14 | import cn.bmob.imdemo.db.NewFriendManager;
15 |
16 | /**联系人
17 | * 一种简洁的Adapter实现方式,可用于多种Item布局的recycleView实现,不用再写ViewHolder啦
18 | * @author :smile
19 | * @project:ContactNewAdapter
20 | * @date :2016-04-27-14:18
21 | */
22 | public class ContactAdapter extends BaseRecyclerAdapter {
23 |
24 | public static final int TYPE_NEW_FRIEND = 0;
25 | public static final int TYPE_ITEM = 1;
26 |
27 | public ContactAdapter(Context context, IMutlipleItem items, Collection datas) {
28 | super(context,items,datas);
29 | }
30 |
31 | @Override
32 | public void bindView(BaseRecyclerHolder holder, Friend friend, int position) {
33 | if(holder.layoutId==R.layout.item_contact){
34 | User user =friend.getFriendUser();
35 | //好友头像
36 | holder.setImageView(user == null ? null : user.getAvatar(), R.mipmap.head, R.id.iv_recent_avatar);
37 | //好友名称
38 | holder.setText(R.id.tv_recent_name,user==null?"未知":user.getUsername());
39 | }else if(holder.layoutId==R.layout.header_new_friend){
40 | if(NewFriendManager.getInstance(context).hasNewFriendInvitation()){
41 | holder.setVisible(R.id.iv_msg_tips,View.VISIBLE);
42 | }else{
43 | holder.setVisible(R.id.iv_msg_tips, View.GONE);
44 | }
45 | }
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/SearchUserAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.view.ViewGroup;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import cn.bmob.imdemo.adapter.base.BaseViewHolder;
10 | import cn.bmob.imdemo.bean.User;
11 |
12 | /**
13 | * @author :smile
14 | * @project:SearchUserAdapter
15 | * @date :2016-01-22-14:18
16 | */
17 | public class SearchUserAdapter extends RecyclerView.Adapter{
18 |
19 | private List users = new ArrayList<>();
20 |
21 | public SearchUserAdapter() {
22 | }
23 |
24 | public void setDatas(List list) {
25 | users.clear();
26 | if (null != list) {
27 | users.addAll(list);
28 | }
29 | }
30 |
31 | /**获取用户
32 | * @param position
33 | * @return
34 | */
35 | public User getItem(int position){
36 | return users.get(position);
37 | }
38 |
39 | private OnRecyclerViewListener onRecyclerViewListener;
40 |
41 | public void setOnRecyclerViewListener(OnRecyclerViewListener onRecyclerViewListener) {
42 | this.onRecyclerViewListener = onRecyclerViewListener;
43 | }
44 |
45 | @Override
46 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
47 | return new SearchUserHolder(parent.getContext(), parent, onRecyclerViewListener);
48 | }
49 |
50 | @Override
51 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
52 | ((BaseViewHolder)holder).bindData(users.get(position));
53 | }
54 |
55 | @Override
56 | public int getItemViewType(int position) {
57 | return 1;
58 | }
59 |
60 | @Override
61 | public int getItemCount() {
62 | return users.size();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/bean/AddFriendMessage.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.bean;
2 |
3 | import android.text.TextUtils;
4 |
5 | import org.json.JSONObject;
6 |
7 | import cn.bmob.imdemo.Config;
8 | import cn.bmob.imdemo.db.NewFriend;
9 | import cn.bmob.newim.bean.BmobIMExtraMessage;
10 | import cn.bmob.newim.bean.BmobIMMessage;
11 | import com.orhanobut.logger.Logger;
12 |
13 | /**添加好友请求
14 | * @author :smile
15 | * @project:AddFriendMessage
16 | * @date :2016-01-30-17:28
17 | */
18 | public class AddFriendMessage extends BmobIMExtraMessage{
19 |
20 | public AddFriendMessage(){}
21 |
22 | /**将BmobIMMessage转成NewFriend
23 | * @param msg 消息
24 | * @return
25 | */
26 | public static NewFriend convert(BmobIMMessage msg){
27 | NewFriend add =new NewFriend();
28 | String content = msg.getContent();
29 | add.setMsg(content);
30 | add.setTime(msg.getCreateTime());
31 | add.setStatus(Config.STATUS_VERIFY_NONE);
32 | try {
33 | String extra = msg.getExtra();
34 | if(!TextUtils.isEmpty(extra)){
35 | JSONObject json =new JSONObject(extra);
36 | String name = json.getString("name");
37 | add.setName(name);
38 | String avatar = json.getString("avatar");
39 | add.setAvatar(avatar);
40 | add.setUid(json.getString("uid"));
41 | }else{
42 | Logger.i("AddFriendMessage的extra为空");
43 | }
44 | } catch (Exception e) {
45 | e.printStackTrace();
46 | }
47 | return add;
48 | }
49 |
50 |
51 | @Override
52 | public String getMsgType() {
53 | return "add";
54 | }
55 |
56 | @Override
57 | public boolean isTransient() {
58 | //设置为true,表明为暂态消息,那么这条消息并不会保存到本地db中,SDK只负责发送出去
59 | //设置为false,则会保存到指定会话的数据库中
60 | return true;
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | BmobIM2.0
3 | Settings
4 | 请输入用户名…
5 | 请输入密码…
6 | 请再次输入密码…
7 | 登录
8 | 注册
9 | 还没有账号?
10 | 立即注册 >
11 | 账号
12 | 密码
13 | 确认密码
14 |
15 | 会话
16 | 联系人
17 | 设置
18 |
19 | 头像
20 | 昵称
21 | 账号
22 | 接受
23 | 新的朋友
24 |
25 | 聊天
26 | 添加好友
27 |
28 | 接收新消息通知
29 | 个人资料
30 | 黑名单
31 | 声音
32 | 震动
33 | 退出登陆
34 |
35 | 长按说话
36 | 照片
37 | 拍摄
38 | 位置
39 | 手指上滑,取消发送
40 | 松开手指,取消发送
41 | 还可以说%1$s秒
42 | 录音时间太短
43 |
44 | Hello blank fragment
45 | UserInfoActivity
46 |
47 |
48 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/BmobIMApplication.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo;
2 |
3 | import android.app.Application;
4 |
5 | import com.orhanobut.logger.Logger;
6 |
7 | import java.io.BufferedReader;
8 | import java.io.File;
9 | import java.io.FileReader;
10 |
11 | import cn.bmob.imdemo.base.UniversalImageLoader;
12 | import cn.bmob.newim.BmobIM;
13 |
14 | /**
15 | * @author :smile
16 | * @project:BmobIMApplication
17 | * @date :2016-01-13-10:19
18 | */
19 | public class BmobIMApplication extends Application{
20 |
21 | private static BmobIMApplication INSTANCE;
22 | public static BmobIMApplication INSTANCE(){
23 | return INSTANCE;
24 | }
25 | private void setInstance(BmobIMApplication app) {
26 | setBmobIMApplication(app);
27 | }
28 | private static void setBmobIMApplication(BmobIMApplication a) {
29 | BmobIMApplication.INSTANCE = a;
30 | }
31 |
32 | @Override
33 | public void onCreate() {
34 | super.onCreate();
35 | setInstance(this);
36 | //初始化
37 | Logger.init("smile");
38 | //只有主进程运行的时候才需要初始化
39 | if (getApplicationInfo().packageName.equals(getMyProcessName())){
40 | //im初始化
41 | BmobIM.init(this);
42 | //注册消息接收器
43 | BmobIM.registerDefaultMessageHandler(new DemoMessageHandler(this));
44 | }
45 | //uil初始化
46 | UniversalImageLoader.initImageLoader(this);
47 | }
48 |
49 | /**
50 | * 获取当前运行的进程名
51 | * @return
52 | */
53 | public static String getMyProcessName() {
54 | try {
55 | File file = new File("/proc/" + android.os.Process.myPid() + "/" + "cmdline");
56 | BufferedReader mBufferedReader = new BufferedReader(new FileReader(file));
57 | String processName = mBufferedReader.readLine().trim();
58 | mBufferedReader.close();
59 | return processName;
60 | } catch (Exception e) {
61 | e.printStackTrace();
62 | return null;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/activity_search_user.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
13 |
14 |
26 |
27 |
37 |
38 |
39 |
44 |
45 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_contact.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
23 |
24 |
39 |
40 |
41 |
42 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/ConversationAdapter.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 |
6 | import java.util.Collection;
7 | import java.util.List;
8 |
9 | import cn.bmob.imdemo.R;
10 | import cn.bmob.imdemo.adapter.base.BaseRecyclerAdapter;
11 | import cn.bmob.imdemo.adapter.base.BaseRecyclerHolder;
12 | import cn.bmob.imdemo.adapter.base.IMutlipleItem;
13 | import cn.bmob.imdemo.bean.Conversation;
14 | import cn.bmob.imdemo.util.TimeUtil;
15 | import cn.bmob.newim.BmobIM;
16 | import cn.bmob.newim.bean.BmobIMConversation;
17 | import cn.bmob.newim.bean.BmobIMMessage;
18 | import cn.bmob.newim.bean.BmobIMMessageType;
19 |
20 | /**
21 | * 使用进一步封装的Conversation,教大家怎么自定义会话列表
22 | * @author smile
23 | */
24 | public class ConversationAdapter extends BaseRecyclerAdapter {
25 |
26 | public ConversationAdapter(Context context, IMutlipleItem items, Collection datas) {
27 | super(context,items,datas);
28 | }
29 |
30 | @Override
31 | public void bindView(BaseRecyclerHolder holder, Conversation conversation, int position) {
32 | holder.setText(R.id.tv_recent_msg,conversation.getLastMessageContent());
33 | holder.setText(R.id.tv_recent_time,TimeUtil.getChatTime(false,conversation.getLastMessageTime()));
34 | //会话图标
35 | Object obj = conversation.getAvatar();
36 | if(obj instanceof String){
37 | String avatar=(String)obj;
38 | holder.setImageView(avatar, R.mipmap.head, R.id.iv_recent_avatar);
39 | }else{
40 | int defaultRes = (int)obj;
41 | holder.setImageView(null, defaultRes, R.id.iv_recent_avatar);
42 | }
43 | //会话标题
44 | holder.setText(R.id.tv_recent_name, conversation.getcName());
45 | //查询指定未读消息数
46 | long unread = conversation.getUnReadCount();
47 | if(unread>0){
48 | holder.setVisible(R.id.tv_recent_unread, View.VISIBLE);
49 | holder.setText(R.id.tv_recent_unread, String.valueOf(unread));
50 | }else{
51 | holder.setVisible(R.id.tv_recent_unread, View.GONE);
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/ui/RegisterActivity.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.ui;
2 |
3 | import android.os.Bundle;
4 | import android.view.View;
5 | import android.widget.Button;
6 | import android.widget.EditText;
7 |
8 | import org.greenrobot.eventbus.EventBus;
9 |
10 | import butterknife.Bind;
11 | import butterknife.OnClick;
12 | import cn.bmob.imdemo.R;
13 | import cn.bmob.imdemo.base.ParentWithNaviActivity;
14 | import cn.bmob.imdemo.event.FinishEvent;
15 | import cn.bmob.imdemo.model.BaseModel;
16 | import cn.bmob.imdemo.model.UserModel;
17 | import cn.bmob.v3.exception.BmobException;
18 | import cn.bmob.v3.listener.LogInListener;
19 |
20 | /**注册界面
21 | * @author :smile
22 | * @project:RegisterActivity
23 | * @date :2016-01-15-18:23
24 | */
25 | public class RegisterActivity extends ParentWithNaviActivity {
26 |
27 | @Bind(R.id.et_username)
28 | EditText et_username;
29 | @Bind(R.id.et_password)
30 | EditText et_password;
31 | @Bind(R.id.btn_register)
32 | Button btn_register;
33 |
34 | @Bind(R.id.et_password_again)
35 | EditText et_password_again;
36 |
37 | @Override
38 | protected String title() {
39 | return "注册";
40 | }
41 |
42 | @Override
43 | protected void onCreate(Bundle savedInstanceState) {
44 | super.onCreate(savedInstanceState);
45 | setContentView(R.layout.activity_register);
46 | initNaviView();
47 | }
48 |
49 | @OnClick(R.id.btn_register)
50 | public void onRegisterClick(View view){
51 | UserModel.getInstance().register(et_username.getText().toString(), et_password.getText().toString(),et_password_again.getText().toString(),new LogInListener() {
52 | @Override
53 | public void done(Object o, BmobException e) {
54 | if(e==null){
55 | EventBus.getDefault().post(new FinishEvent());
56 | startActivity(MainActivity.class, null, true);
57 | }else{
58 | if(e.getErrorCode()== BaseModel.CODE_NOT_EQUAL){
59 | et_password_again.setText("");
60 | }
61 | toast(e.getMessage()+"("+e.getErrorCode()+")");
62 | }
63 | }
64 | });
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/NewIM/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 22
5 | buildToolsVersion "22.0.1"
6 |
7 | aaptOptions.cruncherEnabled = false
8 | aaptOptions.useNewCruncher = false
9 |
10 | defaultConfig {
11 | applicationId "cn.bmob.imdemo"
12 | minSdkVersion 14
13 | targetSdkVersion 22
14 | versionCode 1
15 | versionName "1.0"
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | //自动删除 unaligned .apks
22 | applicationVariants.all { variant ->
23 | variant.assemble.doLast {
24 | variant.outputs.each { output ->
25 | File unaligned = output.packageApplication.outputFile;
26 | File aligned = output.outputFile
27 | if (!unaligned.getName().equalsIgnoreCase(aligned.getName())) {
28 | println "deleting " + unaligned.getName()
29 | unaligned.delete()
30 | }
31 | }
32 | }
33 | }
34 | }
35 | }
36 | dexOptions{
37 | incremental false
38 | }
39 |
40 | lintOptions {
41 | abortOnError false
42 | //忽略警告
43 | ignoreWarnings true
44 | }
45 |
46 | compileOptions {
47 | sourceCompatibility JavaVersion.VERSION_1_7
48 | targetCompatibility JavaVersion.VERSION_1_7
49 | }
50 | }
51 |
52 | dependencies {
53 | compile fileTree(dir: 'libs', include: ['*.jar'])
54 | testCompile 'junit:junit:4.12'
55 | compile('com.android.support:appcompat-v7:22.2.0') {
56 | exclude module: 'support-annotations'
57 | }
58 | compile 'com.android.support:recyclerview-v7:22.2.0'
59 | compile 'com.jakewharton:butterknife:7.0.1'
60 | compile 'com.orhanobut:logger:1.4'
61 | compile 'org.greenrobot:eventbus:3.0.0'
62 | //bmob-im:自2.0.5开始提供aar格式:包含BmobNewIM_xxxx.jar、androidasync_2.1.6.jar、bmob_im_notification_strings.xml
63 | compile 'cn.bmob.android:bmob-im:2.0.5@aar'
64 | //bmob-sdk:3.4.7
65 | compile 'cn.bmob.android:bmob-sdk:3.4.7-aar'
66 | }
67 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/activity_chat.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
14 |
15 |
20 |
24 |
25 |
26 |
27 |
35 |
36 |
43 |
44 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/base/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.base;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.os.IBinder;
8 | import android.support.v4.app.Fragment;
9 | import android.view.inputmethod.InputMethodManager;
10 | import android.widget.Toast;
11 |
12 | import com.orhanobut.logger.Logger;
13 |
14 | import cn.bmob.imdemo.Config;
15 |
16 | /**基类
17 | * @author :smile
18 | * @project:BaseActivity
19 | * @date :2016-01-15-18:23
20 | */
21 | public class BaseFragment extends Fragment {
22 |
23 | protected void runOnMain(Runnable runnable) {
24 | getActivity().runOnUiThread(runnable);
25 | }
26 |
27 | protected final static String NULL = "";
28 | private Toast toast;
29 | public void toast(final Object obj) {
30 | try {
31 | runOnMain(new Runnable() {
32 |
33 | @Override
34 | public void run() {
35 | if (toast == null)
36 | toast = Toast.makeText(getActivity(), NULL,Toast.LENGTH_SHORT);
37 | toast.setText(obj.toString());
38 | toast.show();
39 | }
40 | });
41 | } catch (Exception e) {
42 | e.printStackTrace();
43 | }
44 | }
45 |
46 | public void hideSoftInput(IBinder token) {
47 | if (token != null) {
48 | InputMethodManager im = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
49 | im.hideSoftInputFromWindow(token,InputMethodManager.HIDE_NOT_ALWAYS);
50 | }
51 | }
52 |
53 | /**启动指定Activity
54 | * @param target
55 | * @param bundle
56 | */
57 | public void startActivity(Class extends Activity> target, Bundle bundle) {
58 | Intent intent = new Intent();
59 | intent.setClass(getActivity(), target);
60 | if (bundle != null)
61 | intent.putExtra(getActivity().getPackageName(), bundle);
62 | getActivity().startActivity(intent);
63 | }
64 |
65 | /**Log日志
66 | * @param msg
67 | */
68 | public void log(String msg){
69 | if(Config.DEBUG){
70 | Logger.i(msg);
71 | }
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/include_navi.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
20 |
21 |
31 |
32 |
40 |
41 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_chat_received_message.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
23 |
24 |
32 |
33 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/ui/LoginActivity.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.ui;
2 |
3 | import android.os.Bundle;
4 | import android.view.View;
5 | import android.widget.Button;
6 | import android.widget.EditText;
7 | import android.widget.TextView;
8 |
9 | import org.greenrobot.eventbus.Subscribe;
10 |
11 | import butterknife.Bind;
12 | import butterknife.OnClick;
13 | import cn.bmob.imdemo.R;
14 | import cn.bmob.imdemo.base.BaseActivity;
15 | import cn.bmob.imdemo.bean.User;
16 | import cn.bmob.imdemo.event.FinishEvent;
17 | import cn.bmob.imdemo.model.UserModel;
18 | import cn.bmob.newim.BmobIM;
19 | import cn.bmob.newim.bean.BmobIMUserInfo;
20 | import cn.bmob.v3.exception.BmobException;
21 | import cn.bmob.v3.listener.LogInListener;
22 |
23 | /**登陆界面
24 | * @author :smile
25 | * @project:LoginActivity
26 | * @date :2016-01-15-18:23
27 | */
28 | public class LoginActivity extends BaseActivity {
29 |
30 | @Bind(R.id.et_username)
31 | EditText et_username;
32 | @Bind(R.id.et_password)
33 | EditText et_password;
34 | @Bind(R.id.btn_login)
35 | Button btn_login;
36 | @Bind(R.id.tv_register)
37 | TextView tv_register;
38 |
39 | @Override
40 | protected void onCreate(Bundle savedInstanceState) {
41 | super.onCreate(savedInstanceState);
42 | setContentView(R.layout.activity_login);
43 | }
44 |
45 | @OnClick(R.id.btn_login)
46 | public void onLoginClick(View view){
47 | UserModel.getInstance().login(et_username.getText().toString(), et_password.getText().toString(), new LogInListener() {
48 |
49 | @Override
50 | public void done(Object o, BmobException e) {
51 | if (e == null) {
52 | User user =(User)o;
53 | BmobIM.getInstance().updateUserInfo(new BmobIMUserInfo(user.getObjectId(), user.getUsername(), user.getAvatar()));
54 | startActivity(MainActivity.class, null, true);
55 | } else {
56 | toast(e.getMessage() + "(" + e.getErrorCode() + ")");
57 | }
58 | }
59 | });
60 | }
61 |
62 | @OnClick(R.id.tv_register)
63 | public void onRegisterClick(View view){
64 | startActivity(RegisterActivity.class, null, false);
65 | }
66 |
67 | @Subscribe
68 | public void onEventMainThread(FinishEvent event){
69 | finish();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/header_new_friend.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
17 |
18 |
25 |
26 |
34 |
35 |
36 |
37 |
49 |
50 |
51 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/db/NewFriend.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.db;
2 |
3 | // THIS CODE IS GENERATED BY greenDAO, EDIT ONLY INSIDE THE "KEEP"-SECTIONS
4 |
5 | // KEEP INCLUDES - put your custom includes here
6 | // KEEP INCLUDES END
7 | /**
8 | * Entity mapped to table "newfriend".
9 | */
10 | public class NewFriend implements java.io.Serializable {
11 |
12 | private Long id;
13 | private String uid;
14 | private String msg;
15 | private String name;
16 | private String avatar;
17 | private Integer status;
18 | private Long time;
19 |
20 | // KEEP FIELDS - put your custom fields here
21 | // KEEP FIELDS END
22 |
23 | public NewFriend() {
24 | }
25 |
26 | public NewFriend(Long id) {
27 | this.id = id;
28 | }
29 |
30 | public NewFriend(Long id, String uid, String msg, String name, String avatar, Integer status, Long time) {
31 | this.id = id;
32 | this.uid = uid;
33 | this.msg = msg;
34 | this.name = name;
35 | this.avatar = avatar;
36 | this.status = status;
37 | this.time = time;
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 getMsg() {
57 | return msg;
58 | }
59 |
60 | public void setMsg(String msg) {
61 | this.msg = msg;
62 | }
63 |
64 | public String getName() {
65 | return name;
66 | }
67 |
68 | public void setName(String name) {
69 | this.name = name;
70 | }
71 |
72 | public String getAvatar() {
73 | return avatar;
74 | }
75 |
76 | public void setAvatar(String avatar) {
77 | this.avatar = avatar;
78 | }
79 |
80 | public Integer getStatus() {
81 | return status;
82 | }
83 |
84 | public void setStatus(Integer status) {
85 | this.status = status;
86 | }
87 |
88 | public Long getTime() {
89 | return time;
90 | }
91 |
92 | public void setTime(Long time) {
93 | this.time = time;
94 | }
95 |
96 | // KEEP METHODS - put your custom methods here
97 | // KEEP METHODS END
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/ui/fragment/SetFragment.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.text.TextUtils;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.LinearLayout;
9 | import android.widget.RelativeLayout;
10 | import android.widget.TextView;
11 |
12 | import butterknife.Bind;
13 | import butterknife.ButterKnife;
14 | import butterknife.OnClick;
15 | import cn.bmob.imdemo.R;
16 | import cn.bmob.imdemo.base.ParentWithNaviFragment;
17 | import cn.bmob.imdemo.bean.User;
18 | import cn.bmob.imdemo.model.UserModel;
19 | import cn.bmob.imdemo.ui.LoginActivity;
20 | import cn.bmob.imdemo.ui.UserInfoActivity;
21 | import cn.bmob.newim.BmobIM;
22 | import cn.bmob.v3.BmobUser;
23 |
24 | /**设置
25 | * @author :smile
26 | * @project:SetFragment
27 | * @date :2016-01-25-18:23
28 | */
29 | public class SetFragment extends ParentWithNaviFragment {
30 |
31 | @Bind(R.id.tv_set_name)
32 | TextView tv_set_name;
33 |
34 | @Bind(R.id.layout_info)
35 | RelativeLayout layout_info;
36 |
37 | @Override
38 | protected String title() {
39 | return "设置";
40 | }
41 |
42 | public static SetFragment newInstance() {
43 | SetFragment fragment = new SetFragment();
44 | Bundle args = new Bundle();
45 | fragment.setArguments(args);
46 | return fragment;
47 | }
48 |
49 | public SetFragment() {}
50 |
51 | @Override
52 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
53 | rootView= inflater.inflate(R.layout.fragment_set,container, false);
54 | initNaviView();
55 | ButterKnife.bind(this, rootView);
56 | String username = UserModel.getInstance().getCurrentUser().getUsername();
57 | tv_set_name.setText(TextUtils.isEmpty(username)?"":username);
58 | return rootView;
59 | }
60 |
61 | @OnClick(R.id.layout_info)
62 | public void onInfoClick(View view){
63 | Bundle bundle = new Bundle();
64 | bundle.putSerializable("u", BmobUser.getCurrentUser(getActivity(),User.class));
65 | startActivity(UserInfoActivity.class,bundle);
66 | }
67 |
68 | @OnClick(R.id.btn_logout)
69 | public void onLogoutClick(View view){
70 | UserModel.getInstance().logout();
71 | //可断开连接
72 | BmobIM.getInstance().disConnect();
73 | getActivity().finish();
74 | startActivity(LoginActivity.class,null);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/bean/NewFriendConversation.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.bean;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.text.TextUtils;
6 |
7 | import cn.bmob.imdemo.BmobIMApplication;
8 | import cn.bmob.imdemo.Config;
9 | import cn.bmob.imdemo.R;
10 | import cn.bmob.imdemo.db.NewFriend;
11 | import cn.bmob.imdemo.db.NewFriendManager;
12 | import cn.bmob.imdemo.ui.NewFriendActivity;
13 | import cn.bmob.imdemo.util.TimeUtil;
14 |
15 | /**
16 | * 新朋友会话
17 | * Created by Administrator on 2016/5/25.
18 | */
19 | public class NewFriendConversation extends Conversation{
20 |
21 | NewFriend lastFriend;
22 |
23 | public NewFriendConversation(NewFriend friend){
24 | this.lastFriend=friend;
25 | this.cName="新朋友";
26 | }
27 |
28 | @Override
29 | public String getLastMessageContent() {
30 | if(lastFriend!=null){
31 | Integer status =lastFriend.getStatus();
32 | String name = lastFriend.getName();
33 | if(TextUtils.isEmpty(name)){
34 | name = lastFriend.getUid();
35 | }
36 | //目前的好友请求都是别人发给我的
37 | if(status==null || status== Config.STATUS_VERIFY_NONE||status ==Config.STATUS_VERIFY_READED){
38 | return name+"请求添加好友";
39 | }else{
40 | return "我已添加"+name;
41 | }
42 | }else{
43 | return "";
44 | }
45 | }
46 |
47 | @Override
48 | public long getLastMessageTime() {
49 | if(lastFriend!=null){
50 | return lastFriend.getTime();
51 | }else{
52 | return 0;
53 | }
54 | }
55 |
56 | @Override
57 | public Object getAvatar() {
58 | return R.mipmap.new_friends_icon;
59 | }
60 |
61 | @Override
62 | public int getUnReadCount() {
63 | return NewFriendManager.getInstance(BmobIMApplication.INSTANCE()).getNewInvitationCount();
64 | }
65 |
66 | @Override
67 | public void readAllMessages() {
68 | //批量更新未读未认证的消息为已读状态
69 | NewFriendManager.getInstance(BmobIMApplication.INSTANCE()).updateBatchStatus();
70 | }
71 |
72 | @Override
73 | public void onClick(Context context) {
74 | Intent intent = new Intent();
75 | intent.setClass(context, NewFriendActivity.class);
76 | context.startActivity(intent);
77 | }
78 |
79 | @Override
80 | public void onLongClick(Context context) {
81 | NewFriendManager.getInstance(context).deleteNewFriend(lastFriend);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_chat_received_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
23 |
24 |
33 |
34 |
50 |
51 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/NewIM/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/bean/AgreeAddFriendMessage.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.bean;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.orhanobut.logger.Logger;
6 |
7 | import org.json.JSONObject;
8 |
9 | import cn.bmob.newim.bean.BmobIMExtraMessage;
10 | import cn.bmob.newim.bean.BmobIMMessage;
11 |
12 | /**同意添加好友请求-仅仅只用于发送同意添加好友的消息
13 | * @author smile
14 | * @project AgreeAddFriendMessage
15 | * @date 2016-03-04-10:41
16 | * 接收到对方发送的同意添加自己为好友的请求时,需要做两个事情:1、在本地数据库中新建一个会话,因此需要设置isTransient为false,2、添加对方到自己的好友表中
17 | */
18 | public class AgreeAddFriendMessage extends BmobIMExtraMessage{
19 |
20 | //以下均是从extra里面抽离出来的字段,方便获取
21 | private String uid;//最初的发送方
22 | private Long time;
23 | private String msg;//用于通知栏显示的内容
24 |
25 | @Override
26 | public String getMsgType() {
27 | return "agree";
28 | }
29 |
30 | @Override
31 | public boolean isTransient() {
32 | //如果需要在对方的会话表中新增一条该类型的消息,则设置为false,表明是非暂态会话
33 | //此处将同意添加好友的请求设置为false,为了演示怎样向会话表和消息表中新增一个类型
34 | return false;
35 | }
36 |
37 | public String getUid() {
38 | return uid;
39 | }
40 |
41 | public void setUid(String uid) {
42 | this.uid = uid;
43 | }
44 |
45 | public Long getTime() {
46 | return time;
47 | }
48 |
49 | public void setTime(Long time) {
50 | this.time = time;
51 | }
52 |
53 | public String getMsg() {
54 | return msg;
55 | }
56 |
57 | public void setMsg(String msg) {
58 | this.msg = msg;
59 | }
60 |
61 | public AgreeAddFriendMessage(){}
62 |
63 | /**
64 | * 继承BmobIMMessage的属性
65 | * @param msg
66 | */
67 | private AgreeAddFriendMessage(BmobIMMessage msg){
68 | super.parse(msg);
69 | }
70 |
71 | /**将BmobIMMessage转成AgreeAddFriendMessage
72 | * @param msg 消息
73 | * @return
74 | */
75 | public static AgreeAddFriendMessage convert(BmobIMMessage msg){
76 | AgreeAddFriendMessage agree =new AgreeAddFriendMessage(msg);
77 | try {
78 | String extra = msg.getExtra();
79 | if(!TextUtils.isEmpty(extra)){
80 | JSONObject json =new JSONObject(extra);
81 | Long time = json.getLong("time");
82 | String uid =json.getString("uid");
83 | String m =json.getString("msg");
84 | agree.setMsg(m);
85 | agree.setUid(uid);
86 | agree.setTime(time);
87 | }else{
88 | Logger.i("AgreeAddFriendMessage的extra为空");
89 | }
90 | } catch (Exception e) {
91 | e.printStackTrace();
92 | }
93 | return agree;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/db/dao/DaoMaster.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.db.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 cn.bmob.imdemo.db.dao.NewFriendDao;
12 |
13 | // THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.
14 | /**
15 | * Master of DAO (schema version 1): knows all DAOs.
16 | */
17 | public class DaoMaster extends AbstractDaoMaster {
18 | public static final int SCHEMA_VERSION = 1;
19 |
20 | /** Creates underlying database table using DAOs. */
21 | public static void createAllTables(SQLiteDatabase db, boolean ifNotExists) {
22 | NewFriendDao.createTable(db, ifNotExists);
23 | }
24 |
25 | /** Drops underlying database table using DAOs. */
26 | public static void dropAllTables(SQLiteDatabase db, boolean ifExists) {
27 | NewFriendDao.dropTable(db, ifExists);
28 | }
29 |
30 | public static abstract class OpenHelper extends SQLiteOpenHelper {
31 |
32 | public OpenHelper(Context context, String name, CursorFactory factory) {
33 | super(context, name, factory, SCHEMA_VERSION);
34 | }
35 |
36 | @Override
37 | public void onCreate(SQLiteDatabase db) {
38 | Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION);
39 | createAllTables(db, false);
40 | }
41 | }
42 |
43 | /** WARNING: Drops all table on Upgrade! Use only during development. */
44 | public static class DevOpenHelper extends OpenHelper {
45 | public DevOpenHelper(Context context, String name, CursorFactory factory) {
46 | super(context, name, factory);
47 | }
48 |
49 | @Override
50 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
51 | Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
52 | dropAllTables(db, true);
53 | onCreate(db);
54 | }
55 | }
56 |
57 | public DaoMaster(SQLiteDatabase db) {
58 | super(db, SCHEMA_VERSION);
59 | registerDaoClass(NewFriendDao.class);
60 | }
61 |
62 | public DaoSession newSession() {
63 | return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);
64 | }
65 |
66 | public DaoSession newSession(IdentityScopeType type) {
67 | return new DaoSession(db, type, daoConfigMap);
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/base/BaseViewHolder.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter.base;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.Toast;
12 |
13 | import butterknife.ButterKnife;
14 | import cn.bmob.imdemo.adapter.OnRecyclerViewListener;
15 | import cn.bmob.imdemo.base.BaseActivity;
16 |
17 | /**
18 | * 建议使用BaseRecyclerAdapter
19 | * @param
20 | */
21 | public abstract class BaseViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,View.OnLongClickListener {
22 |
23 | public OnRecyclerViewListener onRecyclerViewListener;
24 | protected Context context;
25 |
26 | public BaseViewHolder(Context context, ViewGroup root, int layoutRes,OnRecyclerViewListener listener) {
27 | super(LayoutInflater.from(context).inflate(layoutRes, root, false));
28 | this.context=context;
29 | ButterKnife.bind(this, itemView);
30 | this.onRecyclerViewListener =listener;
31 | itemView.setOnClickListener(this);
32 | itemView.setOnLongClickListener(this);
33 | }
34 |
35 | public Context getContext() {
36 | return itemView.getContext();
37 | }
38 |
39 | public abstract void bindData(T t);
40 |
41 | private Toast toast;
42 | public void toast(final Object obj) {
43 | try {
44 | ((BaseActivity)context).runOnUiThread(new Runnable() {
45 |
46 | @Override
47 | public void run() {
48 | if (toast == null)
49 | toast = Toast.makeText(context,"", Toast.LENGTH_SHORT);
50 | toast.setText(obj.toString());
51 | toast.show();
52 | }
53 | });
54 | } catch (Exception e) {
55 | e.printStackTrace();
56 | }
57 | }
58 |
59 | @Override
60 | public void onClick(View v) {
61 | if(onRecyclerViewListener!=null){
62 | onRecyclerViewListener.onItemClick(getAdapterPosition());
63 | }
64 | }
65 |
66 | @Override
67 | public boolean onLongClick(View v) {
68 | if(onRecyclerViewListener!=null){
69 | onRecyclerViewListener.onItemLongClick(getAdapterPosition());
70 | }
71 | return true;
72 | }
73 |
74 | /**启动指定Activity
75 | * @param target
76 | * @param bundle
77 | */
78 | public void startActivity(Class extends Activity> target, Bundle bundle) {
79 | Intent intent = new Intent();
80 | intent.setClass(getContext(), target);
81 | if (bundle != null)
82 | intent.putExtra(getContext().getPackageName(), bundle);
83 | getContext().startActivity(intent);
84 | }
85 |
86 | }
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/bean/Conversation.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.bean;
2 |
3 | import android.content.Context;
4 |
5 | import java.io.Serializable;
6 |
7 | import cn.bmob.newim.bean.BmobIMConversationType;
8 |
9 | /**
10 | * 对BmobIMConveration的抽象封装,方便开发者扩展会话类型
11 | * @author smile
12 | * @date 2016-05-25
13 | */
14 | public abstract class Conversation implements Serializable,Comparable{
15 |
16 | /**
17 | * 会话id
18 | */
19 | protected String cId;
20 | /**
21 | * 会话类型
22 | */
23 | protected BmobIMConversationType cType;
24 | /**
25 | * 会话名称
26 | */
27 | protected String cName;
28 |
29 | /**
30 | * 获取头像-用于会话界面显示
31 | */
32 | abstract public Object getAvatar();
33 |
34 | /**
35 | * 获取最后一条消息的时间
36 | */
37 | abstract public long getLastMessageTime();
38 |
39 | /**
40 | * 获取最后一条消息的时间
41 | * @return
42 | */
43 | abstract public String getLastMessageContent();
44 |
45 | /**
46 | * 获取未读会话个数
47 | * @return
48 | */
49 | abstract public int getUnReadCount();
50 |
51 | /**
52 | * 将所有消息标记为已读
53 | */
54 | abstract public void readAllMessages();
55 |
56 | /**
57 | * 点击事件
58 | * @param context
59 | */
60 | abstract public void onClick(Context context);
61 |
62 | /**
63 | * 长按事件
64 | * @param context
65 | */
66 | abstract public void onLongClick(Context context);
67 |
68 | public String getcName() {
69 | return cName;
70 | }
71 |
72 | public String getcId(){
73 | return cId;
74 | }
75 |
76 | @Override
77 | public boolean equals(Object o) {
78 | if (this == o) return true;
79 | if (o == null || getClass() != o.getClass()) return false;
80 | Conversation that = (Conversation) o;
81 | if (!cId.equals(that.cId)) return false;
82 | return cType == that.cType;
83 | }
84 |
85 | @Override
86 | public int hashCode() {
87 | int result = cId.hashCode();
88 | result = 31 * result + cType.hashCode();
89 | return result;
90 | }
91 |
92 |
93 | @Override
94 | public int compareTo(Object another) {
95 | if (another instanceof Conversation){
96 | Conversation anotherConversation = (Conversation) another;
97 | long timeGap = anotherConversation.getLastMessageTime() - getLastMessageTime();
98 | if (timeGap > 0) return 1;
99 | else if (timeGap < 0) return -1;
100 | return 0;
101 | }else{
102 | throw new ClassCastException();
103 | }
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/ReceiveTextHolder.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import java.text.SimpleDateFormat;
10 |
11 | import butterknife.Bind;
12 | import butterknife.OnClick;
13 | import cn.bmob.imdemo.R;
14 | import cn.bmob.imdemo.adapter.base.BaseViewHolder;
15 | import cn.bmob.imdemo.base.ImageLoaderFactory;
16 | import cn.bmob.newim.bean.BmobIMMessage;
17 | import cn.bmob.newim.bean.BmobIMUserInfo;
18 |
19 | /**
20 | * 接收到的文本类型
21 | */
22 | public class ReceiveTextHolder extends BaseViewHolder {
23 |
24 | @Bind(R.id.iv_avatar)
25 | protected ImageView iv_avatar;
26 |
27 | @Bind(R.id.tv_time)
28 | protected TextView tv_time;
29 |
30 | @Bind(R.id.tv_message)
31 | protected TextView tv_message;
32 |
33 | public ReceiveTextHolder(Context context, ViewGroup root,OnRecyclerViewListener onRecyclerViewListener) {
34 | super(context, root, R.layout.item_chat_received_message,onRecyclerViewListener);
35 | }
36 |
37 | @OnClick({R.id.iv_avatar})
38 | public void onAvatarClick(View view) {
39 |
40 | }
41 |
42 | @Override
43 | public void bindData(Object o) {
44 | final BmobIMMessage message = (BmobIMMessage)o;
45 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
46 | String time = dateFormat.format(message.getCreateTime());
47 | tv_time.setText(time);
48 | final BmobIMUserInfo info = message.getBmobIMUserInfo();
49 | ImageLoaderFactory.getLoader().loadAvator(iv_avatar,info != null ? info.getAvatar() : null, R.mipmap.head);
50 | String content = message.getContent();
51 | tv_message.setText(content);
52 | iv_avatar.setOnClickListener(new View.OnClickListener() {
53 | @Override
54 | public void onClick(View v) {
55 | toast("点击" + info.getName() + "的头像");
56 | }
57 | });
58 | tv_message.setOnClickListener(new View.OnClickListener() {
59 | @Override
60 | public void onClick(View v) {
61 | toast("点击"+message.getContent());
62 | if(onRecyclerViewListener!=null){
63 | onRecyclerViewListener.onItemClick(getAdapterPosition());
64 | }
65 | }
66 | });
67 |
68 | tv_message.setOnLongClickListener(new View.OnLongClickListener() {
69 | @Override
70 | public boolean onLongClick(View v) {
71 | if (onRecyclerViewListener != null) {
72 | onRecyclerViewListener.onItemLongClick(getAdapterPosition());
73 | }
74 | return true;
75 | }
76 | });
77 | }
78 |
79 | public void showTime(boolean isShow) {
80 | tv_time.setVisibility(isShow ? View.VISIBLE : View.GONE);
81 | }
82 | }
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/ReceiveVideoHolder.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import java.text.SimpleDateFormat;
10 |
11 | import butterknife.Bind;
12 | import butterknife.OnClick;
13 | import cn.bmob.imdemo.R;
14 | import cn.bmob.imdemo.adapter.base.BaseViewHolder;
15 | import cn.bmob.imdemo.base.ImageLoaderFactory;
16 | import cn.bmob.newim.bean.BmobIMMessage;
17 | import cn.bmob.newim.bean.BmobIMUserInfo;
18 |
19 | /**
20 | * 接收到的视频类型--这是举个例子,并没有展示出视频缩略图等信息,开发者可自行设置
21 | */
22 | public class ReceiveVideoHolder extends BaseViewHolder {
23 |
24 | @Bind(R.id.iv_avatar)
25 | protected ImageView iv_avatar;
26 |
27 | @Bind(R.id.tv_time)
28 | protected TextView tv_time;
29 |
30 | @Bind(R.id.tv_message)
31 | protected TextView tv_message;
32 |
33 | public ReceiveVideoHolder(Context context, ViewGroup root, OnRecyclerViewListener onRecyclerViewListener) {
34 | super(context, root, R.layout.item_chat_received_message,onRecyclerViewListener);
35 | }
36 |
37 | @OnClick({R.id.iv_avatar})
38 | public void onAvatarClick(View view) {
39 |
40 | }
41 |
42 | @Override
43 | public void bindData(Object o) {
44 | final BmobIMMessage message = (BmobIMMessage)o;
45 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
46 | String time = dateFormat.format(message.getCreateTime());
47 | tv_time.setText(time);
48 | final BmobIMUserInfo info = message.getBmobIMUserInfo();
49 | ImageLoaderFactory.getLoader().loadAvator(iv_avatar,info != null ? info.getAvatar() : null, R.mipmap.head);
50 | String content = message.getContent();
51 | tv_message.setText("接收到的视频文件:"+content);
52 | iv_avatar.setOnClickListener(new View.OnClickListener() {
53 | @Override
54 | public void onClick(View v) {
55 | toast("点击" + info.getName() + "的头像");
56 | }
57 | });
58 |
59 | tv_message.setOnClickListener(new View.OnClickListener() {
60 | @Override
61 | public void onClick(View v) {
62 | toast("点击"+message.getContent());
63 | if(onRecyclerViewListener!=null){
64 | onRecyclerViewListener.onItemClick(getAdapterPosition());
65 | }
66 | }
67 | });
68 |
69 | tv_message.setOnLongClickListener(new View.OnLongClickListener() {
70 | @Override
71 | public boolean onLongClick(View v) {
72 | if (onRecyclerViewListener != null) {
73 | onRecyclerViewListener.onItemLongClick(getAdapterPosition());
74 | }
75 | return true;
76 | }
77 | });
78 | }
79 |
80 | public void showTime(boolean isShow) {
81 | tv_time.setVisibility(isShow ? View.VISIBLE : View.GONE);
82 | }
83 | }
--------------------------------------------------------------------------------
/NewIM/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 1.8
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_chat_received_location.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
23 |
24 |
33 |
34 |
46 |
47 |
55 |
56 |
57 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/ReceiveLocationHolder.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import java.text.SimpleDateFormat;
10 |
11 | import butterknife.Bind;
12 | import cn.bmob.imdemo.R;
13 | import cn.bmob.imdemo.adapter.base.BaseViewHolder;
14 | import cn.bmob.imdemo.base.ImageLoaderFactory;
15 | import cn.bmob.newim.bean.BmobIMLocationMessage;
16 | import cn.bmob.newim.bean.BmobIMMessage;
17 | import cn.bmob.newim.bean.BmobIMUserInfo;
18 |
19 | /**
20 | * 接收到的位置类型
21 | */
22 | public class ReceiveLocationHolder extends BaseViewHolder {
23 |
24 | @Bind(R.id.iv_avatar)
25 | protected ImageView iv_avatar;
26 |
27 | @Bind(R.id.tv_time)
28 | protected TextView tv_time;
29 |
30 | @Bind(R.id.tv_location)
31 | protected TextView tv_location;
32 |
33 | public ReceiveLocationHolder(Context context, ViewGroup root,OnRecyclerViewListener onRecyclerViewListener) {
34 | super(context, root, R.layout.item_chat_received_location,onRecyclerViewListener);
35 | }
36 |
37 | @Override
38 | public void bindData(Object o) {
39 | BmobIMMessage msg = (BmobIMMessage)o;
40 | //用户信息的获取必须在buildFromDB之前,否则会报错'Entity is detached from DAO context'
41 | final BmobIMUserInfo info = msg.getBmobIMUserInfo();
42 | //加载头像
43 | ImageLoaderFactory.getLoader().loadAvator(iv_avatar,info != null ? info.getAvatar() : null, R.mipmap.head);
44 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
45 | String time = dateFormat.format(msg.getCreateTime());
46 | tv_time.setText(time);
47 | //
48 | final BmobIMLocationMessage message = BmobIMLocationMessage.buildFromDB(msg);
49 | tv_location.setText(message.getAddress());
50 | //
51 | tv_location.setOnClickListener(new View.OnClickListener() {
52 | @Override
53 | public void onClick(View v) {
54 | toast("经度:" + message.getLongitude() + ",维度:" + message.getLatitude());
55 | if(onRecyclerViewListener!=null){
56 | onRecyclerViewListener.onItemClick(getAdapterPosition());
57 | }
58 | }
59 | });
60 | tv_location.setOnLongClickListener(new View.OnLongClickListener() {
61 | @Override
62 | public boolean onLongClick(View v) {
63 | if (onRecyclerViewListener != null) {
64 | onRecyclerViewListener.onItemLongClick(getAdapterPosition());
65 | }
66 | return true;
67 | }
68 | });
69 |
70 | iv_avatar.setOnClickListener(new View.OnClickListener() {
71 | @Override
72 | public void onClick(View v) {
73 | toast("点击"+info.getName()+"头像");
74 | }
75 | });
76 | }
77 |
78 | public void showTime(boolean isShow) {
79 | tv_time.setVisibility(isShow ? View.VISIBLE : View.GONE);
80 | }
81 | }
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/util/TimeUtil.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.util;
2 |
3 | import java.text.ParseException;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Calendar;
6 | import java.util.Date;
7 |
8 | /**
9 | * @author :smile
10 | * @project:TimeUtil
11 | * @date :2016-01-26-17:27
12 | */
13 | public class TimeUtil {
14 |
15 | public final static String FORMAT_TIME = "HH:mm";
16 | public final static String FORMAT_DATE_TIME = "yyyy-MM-dd HH:mm";
17 | public final static String FORMAT_DATE_TIME_SECOND = "yyyy-MM-dd HH:mm:ss";
18 | public final static String FORMAT_MONTH_DAY_TIME = "MM-dd HH:mm";
19 |
20 | public static String getFormatToday(String dateFormat) {
21 | Date currentTime = new Date();
22 | SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
23 | return formatter.format(currentTime);
24 | }
25 |
26 | public static Date stringToDate(String dateStr, String dateFormat) {
27 | SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
28 | try {
29 | return formatter.parse(dateStr);
30 | } catch (ParseException e) {
31 | return null;
32 | }
33 | }
34 | public static String dateToString(Date date, String dateFormat) {
35 | SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
36 | return formatter.format(date);
37 | }
38 |
39 | public static String getChatTime(boolean hasYear,long timesamp) {
40 | long clearTime = timesamp;
41 | String result;
42 | SimpleDateFormat sdf = new SimpleDateFormat("dd");
43 | Date today = new Date(System.currentTimeMillis());
44 | Date otherDay = new Date(clearTime);
45 | int temp = Integer.parseInt(sdf.format(today))
46 | - Integer.parseInt(sdf.format(otherDay));
47 | switch (temp) {
48 | case 0:
49 | result = "今天 " + getHourAndMin(clearTime);
50 | break;
51 | case 1:
52 | result = "昨天 " + getHourAndMin(clearTime);
53 | break;
54 | case 2:
55 | result = "前天 " + getHourAndMin(clearTime);
56 | break;
57 | default:
58 | result = getTime(hasYear,clearTime);
59 | break;
60 | }
61 | return result;
62 | }
63 |
64 | public static String getTime(boolean hasYear,long time) {
65 | String pattern=FORMAT_DATE_TIME;
66 | if(!hasYear){
67 | pattern = FORMAT_MONTH_DAY_TIME;
68 | }
69 | SimpleDateFormat format = new SimpleDateFormat(pattern);
70 | return format.format(new Date(time));
71 | }
72 |
73 | public static String getHourAndMin(long time) {
74 | SimpleDateFormat format = new SimpleDateFormat(FORMAT_TIME);
75 | return format.format(new Date(time));
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_chat_received_voice.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
23 |
24 |
33 |
34 |
48 |
49 |
54 |
55 |
56 |
65 |
66 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/activity_register.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
15 |
16 |
29 |
30 |
34 |
35 |
46 |
50 |
61 |
62 |
63 |
64 |
74 |
75 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/base/UniversalImageLoader.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.base;
2 |
3 | import android.content.Context;
4 | import android.text.TextUtils;
5 | import android.util.Log;
6 | import android.widget.ImageView;
7 |
8 | import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
9 | import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache;
10 | import com.nostra13.universalimageloader.core.ImageLoader;
11 | import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
12 | import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
13 | import com.nostra13.universalimageloader.core.download.ImageDownloader;
14 | import com.nostra13.universalimageloader.core.imageaware.ImageAware;
15 | import com.nostra13.universalimageloader.core.imageaware.ImageViewAware;
16 | import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
17 | import com.orhanobut.logger.Logger;
18 |
19 | import cn.bmob.imdemo.util.DisplayConfig;
20 |
21 | /**
22 | * 使用UIL图片框架加载图片,后续方便扩展其他图片框架,比如glide或fresco
23 | * Created by Administrator on 2016/5/24.
24 | */
25 | public class UniversalImageLoader implements ILoader{
26 |
27 | public UniversalImageLoader(){}
28 |
29 | @Override
30 | public void loadAvator(ImageView iv, String url, int defaultRes) {
31 | if(!TextUtils.isEmpty(url)){
32 | display(iv,url,true,defaultRes,null);
33 | } else {
34 | iv.setImageResource(defaultRes);
35 | }
36 | }
37 |
38 | @Override
39 | public void load(ImageView iv, String url, int defaultRes,ImageLoadingListener listener) {
40 | if(!TextUtils.isEmpty(url)){
41 | display(iv,url.trim(),false,defaultRes,listener);
42 | } else {
43 | iv.setImageResource(defaultRes);
44 | }
45 | }
46 |
47 | /**
48 | * 展示图片
49 | * @param iv
50 | * @param url
51 | * @param defaultRes
52 | * @param listener
53 | */
54 | private void display(ImageView iv,String url,boolean isCircle,int defaultRes,ImageLoadingListener listener){
55 | if(!url.equals(iv.getTag())){//增加tag标记,减少UIL的display次数
56 | iv.setTag(url);
57 | //不直接display imageview改为ImageAware,解决ListView滚动时重复加载图片
58 | ImageAware imageAware = new ImageViewAware(iv, false);
59 | ImageLoader.getInstance().displayImage(url, imageAware, DisplayConfig.getDefaultOptions(isCircle,defaultRes),listener);
60 | }
61 | }
62 |
63 | /**
64 | * 初始化ImageLoader
65 | * @param context
66 | */
67 | public static void initImageLoader(Context context) {
68 | ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context);
69 | config.threadPoolSize(3);
70 | config.memoryCache(new WeakMemoryCache());
71 | config.threadPriority(Thread.NORM_PRIORITY - 2);
72 | config.denyCacheImageMultipleSizesInMemory();
73 | config.diskCacheFileNameGenerator(new Md5FileNameGenerator());
74 | config.diskCacheSize(50 * 1024 * 1024); // 50 MiB
75 | config.tasksProcessingOrder(QueueProcessingType.LIFO);
76 | // config.writeDebugLogs(); // Remove for release app
77 | // Initialize ImageLoader with configuration.
78 | ImageLoader.getInstance().init(config.build());
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/base/BaseRecyclerHolder.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter.base;
2 |
3 | import android.graphics.Bitmap;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.util.SparseArray;
6 | import android.view.View;
7 | import android.widget.ImageView;
8 | import android.widget.TextView;
9 |
10 | import cn.bmob.imdemo.base.ImageLoaderFactory;
11 |
12 | /**
13 | * 与BaseRecyclerAdapter一起使用
14 | *
15 | */
16 | public class BaseRecyclerHolder extends RecyclerView.ViewHolder {
17 |
18 | private final SparseArray mViews;
19 | public int layoutId;
20 |
21 | public BaseRecyclerHolder(int layoutId,View itemView) {
22 | super(itemView);
23 | this.layoutId =layoutId;
24 | this.mViews = new SparseArray<>(8);
25 | }
26 |
27 | public SparseArray getAllView() {
28 | return mViews;
29 | }
30 |
31 | /**
32 | * @param viewId
33 | * @return
34 | */
35 | protected T getView(int viewId) {
36 | View view = mViews.get(viewId);
37 | if (view == null) {
38 | view = itemView.findViewById(viewId);
39 | mViews.put(viewId, view);
40 | }
41 | return (T) view;
42 | }
43 |
44 | /**
45 | * @param viewId
46 | * @param text
47 | * @return
48 | */
49 | public BaseRecyclerHolder setText(int viewId, String text) {
50 | TextView view = getView(viewId);
51 | view.setText(text);
52 | return this;
53 | }
54 |
55 | /**
56 | * 设置Enabled
57 | * @param viewId
58 | * @param enable
59 | * @return
60 | */
61 | public BaseRecyclerHolder setEnabled(int viewId,boolean enable){
62 | View v = getView(viewId);
63 | v.setEnabled(enable);
64 | return this;
65 | }
66 |
67 | /**
68 | * 点击事件
69 | * @param viewId
70 | * @param listener
71 | * @return
72 | */
73 | public BaseRecyclerHolder setOnClickListener(int viewId, View.OnClickListener listener){
74 | View v = getView(viewId);
75 | v.setOnClickListener(listener);
76 | return this;
77 | }
78 |
79 | /**
80 | * @param viewId
81 | * @param visibility
82 | * @return
83 | */
84 | public BaseRecyclerHolder setVisible(int viewId,int visibility) {
85 | View view = getView(viewId);
86 | view.setVisibility(visibility);
87 | return this;
88 | }
89 |
90 | /**
91 | * @param viewId
92 | * @param drawableId
93 | * @return
94 | */
95 | public BaseRecyclerHolder setImageResource(int viewId, int drawableId) {
96 | ImageView view = getView(viewId);
97 | view.setImageResource(drawableId);
98 | return this;
99 | }
100 |
101 | /**
102 | * @param viewId
103 | * @param bm
104 | * @return
105 | */
106 | public BaseRecyclerHolder setImageBitmap(int viewId, Bitmap bm) {
107 | ImageView view = getView(viewId);
108 | view.setImageBitmap(bm);
109 | return this;
110 | }
111 |
112 | /**
113 | * @param avatar
114 | * @param defaultRes
115 | * @param viewId
116 | * @return
117 | */
118 | public BaseRecyclerHolder setImageView(String avatar, int defaultRes, int viewId) {
119 | ImageView iv = getView(viewId);
120 | ImageLoaderFactory.getLoader().loadAvator(iv,avatar, defaultRes);
121 | return this;
122 | }
123 | }
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_chat_sent_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
23 |
24 |
32 |
33 |
50 |
51 |
64 |
65 |
75 |
76 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
26 |
27 |
30 |
31 |
34 |
35 |
38 |
39 |
42 |
43 |
46 |
47 |
50 |
51 |
54 |
55 |
58 |
59 |
63 |
64 |
67 |
68 |
71 |
72 |
82 |
83 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_new_friend.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
24 |
25 |
30 |
31 |
44 |
45 |
60 |
61 |
62 |
63 |
74 |
75 |
76 |
77 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
33 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
68 |
71 |
72 |
73 |
74 |
75 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_chat_sent_message.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
23 |
24 |
32 |
33 |
50 |
51 |
64 |
65 |
76 |
77 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/activity_user_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
19 |
20 |
25 |
26 |
33 |
34 |
44 |
45 |
46 |
47 |
48 |
54 |
55 |
60 |
61 |
68 |
69 |
70 |
81 |
82 |
92 |
93 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_chat_sent_location.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
23 |
24 |
33 |
34 |
45 |
46 |
54 |
55 |
56 |
69 |
70 |
80 |
81 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/adapter/ReceiveImageHolder.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.adapter;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.ImageView;
8 | import android.widget.ProgressBar;
9 | import android.widget.TextView;
10 |
11 | import com.nostra13.universalimageloader.core.assist.FailReason;
12 | import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
13 |
14 | import java.text.SimpleDateFormat;
15 |
16 | import butterknife.Bind;
17 | import cn.bmob.imdemo.R;
18 | import cn.bmob.imdemo.adapter.base.BaseViewHolder;
19 | import cn.bmob.imdemo.base.ImageLoaderFactory;
20 | import cn.bmob.newim.bean.BmobIMImageMessage;
21 | import cn.bmob.newim.bean.BmobIMMessage;
22 | import cn.bmob.newim.bean.BmobIMUserInfo;
23 |
24 | /**
25 | * 接收到的文本类型
26 | */
27 | public class ReceiveImageHolder extends BaseViewHolder {
28 |
29 | @Bind(R.id.iv_avatar)
30 | protected ImageView iv_avatar;
31 |
32 | @Bind(R.id.tv_time)
33 | protected TextView tv_time;
34 |
35 | @Bind(R.id.iv_picture)
36 | protected ImageView iv_picture;
37 | @Bind(R.id.progress_load)
38 | protected ProgressBar progress_load;
39 |
40 | public ReceiveImageHolder(Context context, ViewGroup root,OnRecyclerViewListener onRecyclerViewListener) {
41 | super(context, root, R.layout.item_chat_received_image,onRecyclerViewListener);
42 | }
43 |
44 | @Override
45 | public void bindData(Object o) {
46 | BmobIMMessage msg = (BmobIMMessage)o;
47 | //用户信息的获取必须在buildFromDB之前,否则会报错'Entity is detached from DAO context'
48 | final BmobIMUserInfo info = msg.getBmobIMUserInfo();
49 | ImageLoaderFactory.getLoader().loadAvator(iv_avatar,info != null ? info.getAvatar() : null, R.mipmap.head);
50 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
51 | String time = dateFormat.format(msg.getCreateTime());
52 | tv_time.setText(time);
53 | //可使用buildFromDB方法转化为指定类型的消息
54 | final BmobIMImageMessage message = BmobIMImageMessage.buildFromDB(false,msg);
55 | //显示图片
56 | ImageLoaderFactory.getLoader().load(iv_picture,message.getRemoteUrl(), R.mipmap.ic_launcher,new ImageLoadingListener(){;
57 |
58 | @Override
59 | public void onLoadingStarted(String s, View view) {
60 | progress_load.setVisibility(View.VISIBLE);
61 | }
62 |
63 | @Override
64 | public void onLoadingComplete(String s, View view, Bitmap bitmap) {
65 | progress_load.setVisibility(View.INVISIBLE);
66 | }
67 |
68 | @Override
69 | public void onLoadingCancelled(String s, View view) {
70 | progress_load.setVisibility(View.INVISIBLE);
71 | }
72 |
73 | @Override
74 | public void onLoadingFailed(String s, View view, FailReason failReason) {
75 | progress_load.setVisibility(View.INVISIBLE);
76 | }
77 | });
78 |
79 | iv_avatar.setOnClickListener(new View.OnClickListener() {
80 | @Override
81 | public void onClick(View v) {
82 | toast("点击" + info.getName() + "的头像");
83 | }
84 | });
85 |
86 | iv_picture.setOnClickListener(new View.OnClickListener() {
87 | @Override
88 | public void onClick(View v) {
89 | toast("点击图片:"+message.getRemoteUrl()+"");
90 | if(onRecyclerViewListener!=null){
91 | onRecyclerViewListener.onItemClick(getAdapterPosition());
92 | }
93 | }
94 | });
95 |
96 | iv_picture.setOnLongClickListener(new View.OnLongClickListener() {
97 | @Override
98 | public boolean onLongClick(View v) {
99 | if (onRecyclerViewListener != null) {
100 | onRecyclerViewListener.onItemLongClick(getAdapterPosition());
101 | }
102 | return true;
103 | }
104 | });
105 |
106 | }
107 |
108 | public void showTime(boolean isShow) {
109 | tv_time.setVisibility(isShow ? View.VISIBLE : View.GONE);
110 | }
111 | }
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/ui/SearchUserActivity.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.ui;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.widget.SwipeRefreshLayout;
5 | import android.support.v7.widget.LinearLayoutManager;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.text.TextUtils;
8 | import android.view.View;
9 | import android.widget.Button;
10 | import android.widget.EditText;
11 |
12 | import com.orhanobut.logger.Logger;
13 |
14 | import org.greenrobot.eventbus.Subscribe;
15 |
16 | import java.util.List;
17 |
18 | import butterknife.Bind;
19 | import butterknife.OnClick;
20 | import cn.bmob.imdemo.R;
21 | import cn.bmob.imdemo.adapter.OnRecyclerViewListener;
22 | import cn.bmob.imdemo.bean.User;
23 | import cn.bmob.imdemo.adapter.SearchUserAdapter;
24 | import cn.bmob.imdemo.base.ParentWithNaviActivity;
25 | import cn.bmob.imdemo.model.BaseModel;
26 | import cn.bmob.imdemo.model.UserModel;
27 | import cn.bmob.v3.listener.FindListener;
28 |
29 | /**搜索好友
30 | * @author :smile
31 | * @project:SearchUserActivity
32 | * @date :2016-01-25-18:23
33 | */
34 | public class SearchUserActivity extends ParentWithNaviActivity {
35 |
36 | @Bind(R.id.et_find_name)
37 | EditText et_find_name;
38 | @Bind(R.id.sw_refresh)
39 | SwipeRefreshLayout sw_refresh;
40 | @Bind(R.id.btn_search)
41 | Button btn_search;
42 | @Bind(R.id.rc_view)
43 | RecyclerView rc_view;
44 | LinearLayoutManager layoutManager;
45 | SearchUserAdapter adapter;
46 |
47 | @Override
48 | protected String title() {
49 | return "搜索好友";
50 | }
51 |
52 | @Override
53 | protected void onCreate(Bundle savedInstanceState) {
54 | super.onCreate(savedInstanceState);
55 | setContentView(R.layout.activity_search_user);
56 | initNaviView();
57 | adapter =new SearchUserAdapter();
58 | layoutManager = new LinearLayoutManager(this);
59 | rc_view.setLayoutManager(layoutManager);
60 | rc_view.setAdapter(adapter);
61 | sw_refresh.setEnabled(true);
62 | sw_refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
63 | @Override
64 | public void onRefresh() {
65 | query();
66 | }
67 | });
68 | adapter.setOnRecyclerViewListener(new OnRecyclerViewListener() {
69 | @Override
70 | public void onItemClick(int position) {
71 | Bundle bundle = new Bundle();
72 | User user = adapter.getItem(position);
73 | bundle.putSerializable("u", user);
74 | startActivity(UserInfoActivity.class, bundle, false);
75 | }
76 |
77 | @Override
78 | public boolean onItemLongClick(int position) {
79 | return true;
80 | }
81 | });
82 | }
83 |
84 | @OnClick(R.id.btn_search)
85 | public void onSearchClick(View view){
86 | sw_refresh.setRefreshing(true);
87 | query();
88 | }
89 |
90 | public void query(){
91 | String name =et_find_name.getText().toString();
92 | if(TextUtils.isEmpty(name)){
93 | toast("请填写用户名");
94 | sw_refresh.setRefreshing(false);
95 | return;
96 | }
97 | UserModel.getInstance().queryUsers(name, BaseModel.DEFAULT_LIMIT, new FindListener() {
98 | @Override
99 | public void onSuccess(List list) {
100 | sw_refresh.setRefreshing(false);
101 | adapter.setDatas(list);
102 | adapter.notifyDataSetChanged();
103 | }
104 |
105 | @Override
106 | public void onError(int i, String s) {
107 | sw_refresh.setRefreshing(false);
108 | adapter.setDatas(null);
109 | adapter.notifyDataSetChanged();
110 | toast(s + "(" + i + ")");
111 | }
112 | });
113 | }
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/item_conversation.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
23 |
24 |
38 |
39 |
54 |
55 |
69 |
70 |
84 |
85 |
86 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
19 |
20 |
26 |
27 |
40 |
41 |
45 |
46 |
57 |
58 |
59 |
69 |
70 |
71 |
78 |
79 |
86 |
87 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/bean/PrivateConversation.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.bean;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.text.TextUtils;
7 |
8 | import java.util.List;
9 |
10 | import cn.bmob.imdemo.R;
11 | import cn.bmob.imdemo.ui.ChatActivity;
12 | import cn.bmob.imdemo.util.TimeUtil;
13 | import cn.bmob.newim.BmobIM;
14 | import cn.bmob.newim.bean.BmobIMConversation;
15 | import cn.bmob.newim.bean.BmobIMConversationType;
16 | import cn.bmob.newim.bean.BmobIMMessage;
17 | import cn.bmob.newim.bean.BmobIMMessageType;
18 |
19 | /**
20 | * 私聊会话
21 | * Created by Administrator on 2016/5/25.
22 | */
23 | public class PrivateConversation extends Conversation{
24 |
25 | private BmobIMConversation conversation;
26 | private BmobIMMessage lastMsg;
27 |
28 | public PrivateConversation(BmobIMConversation conversation){
29 | this.conversation = conversation;
30 | cType = BmobIMConversationType.setValue(conversation.getConversationType());
31 | cId = conversation.getConversationId();
32 | if (cType == BmobIMConversationType.PRIVATE){
33 | cName=conversation.getConversationTitle();
34 | if (TextUtils.isEmpty(cName)) cName = cId;
35 | }else{
36 | cName="未知会话";
37 | }
38 | List msgs =conversation.getMessages();
39 | if(msgs!=null && msgs.size()>0){
40 | lastMsg =msgs.get(0);
41 | }
42 | }
43 |
44 | @Override
45 | public void readAllMessages() {
46 | conversation.updateLocalCache();
47 | }
48 |
49 | @Override
50 | public Object getAvatar() {
51 | if (cType == BmobIMConversationType.PRIVATE){
52 | String avatar = conversation.getConversationIcon();
53 | if (TextUtils.isEmpty(avatar)){//头像为空,使用默认头像
54 | return R.mipmap.head;
55 | }else{
56 | return avatar;
57 | }
58 | }else{
59 | return R.mipmap.head;
60 | }
61 | }
62 |
63 | @Override
64 | public String getLastMessageContent() {
65 | if(lastMsg!=null){
66 | String content =lastMsg.getContent();
67 | if(lastMsg.getMsgType().equals(BmobIMMessageType.TEXT.getType()) || lastMsg.getMsgType().equals("agree")){
68 | return content;
69 | }else if(lastMsg.getMsgType().equals(BmobIMMessageType.IMAGE.getType())){
70 | return "[图片]";
71 | }else if(lastMsg.getMsgType().equals(BmobIMMessageType.VOICE.getType())){
72 | return "[语音]";
73 | }else if(lastMsg.getMsgType().equals(BmobIMMessageType.LOCATION.getType())){
74 | return"[位置]";
75 | }else if(lastMsg.getMsgType().equals(BmobIMMessageType.VIDEO.getType())){
76 | return "[视频]";
77 | }else{//开发者自定义的消息类型,需要自行处理
78 | return "[未知]";
79 | }
80 | }else{//防止消息错乱
81 | return "";
82 | }
83 | }
84 |
85 | @Override
86 | public long getLastMessageTime() {
87 | if(lastMsg!=null) {
88 | return lastMsg.getCreateTime();
89 | }else{
90 | return 0;
91 | }
92 | }
93 |
94 | @Override
95 | public int getUnReadCount() {
96 | return (int)BmobIM.getInstance().getUnReadCount(conversation.getConversationId());
97 | }
98 |
99 | @Override
100 | public void onClick(Context context) {
101 | Intent intent = new Intent();
102 | intent.setClass(context, ChatActivity.class);
103 | Bundle bundle = new Bundle();
104 | bundle.putSerializable("c", conversation);
105 | if (bundle != null) {
106 | intent.putExtra(context.getPackageName(), bundle);
107 | }
108 | context.startActivity(intent);
109 | }
110 |
111 | @Override
112 | public void onLongClick(Context context) {
113 | //以下两种方式均可以删除会话
114 | // BmobIM.getInstance().deleteConversation(conversation.getConversationId());
115 | BmobIM.getInstance().deleteConversation(conversation);
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/NewIM/app/src/main/java/cn/bmob/imdemo/ui/UserInfoActivity.java:
--------------------------------------------------------------------------------
1 | package cn.bmob.imdemo.ui;
2 |
3 | import android.os.Bundle;
4 | import android.view.View;
5 | import android.widget.Button;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | import butterknife.Bind;
13 | import butterknife.OnClick;
14 | import cn.bmob.imdemo.R;
15 | import cn.bmob.imdemo.base.ImageLoaderFactory;
16 | import cn.bmob.imdemo.base.ParentWithNaviActivity;
17 | import cn.bmob.imdemo.bean.AddFriendMessage;
18 | import cn.bmob.imdemo.bean.User;
19 | import cn.bmob.newim.BmobIM;
20 | import cn.bmob.newim.bean.BmobIMConversation;
21 | import cn.bmob.newim.bean.BmobIMMessage;
22 | import cn.bmob.newim.bean.BmobIMUserInfo;
23 | import cn.bmob.newim.core.BmobIMClient;
24 | import cn.bmob.newim.listener.MessageSendListener;
25 | import cn.bmob.v3.BmobUser;
26 | import cn.bmob.v3.exception.BmobException;
27 |
28 | /**
29 | * 用户资料
30 | */
31 | public class UserInfoActivity extends ParentWithNaviActivity {
32 |
33 | @Bind(R.id.iv_avator)
34 | ImageView iv_avator;
35 | @Bind(R.id.tv_name)
36 | TextView tv_name;
37 |
38 | @Bind(R.id.btn_add_friend)
39 | Button btn_add_friend;
40 | @Bind(R.id.btn_chat)
41 | Button btn_chat;
42 |
43 | User user;
44 | BmobIMUserInfo info;
45 | @Override
46 | protected String title() {
47 | return "个人资料";
48 | }
49 |
50 | @Override
51 | protected void onCreate(Bundle savedInstanceState) {
52 | super.onCreate(savedInstanceState);
53 | setContentView(R.layout.activity_user_info);
54 | initNaviView();
55 | user=(User)getBundle().getSerializable("u");
56 | if(user.getObjectId().equals(getCurrentUid())){
57 | btn_add_friend.setVisibility(View.GONE);
58 | btn_chat.setVisibility(View.GONE);
59 | }else{
60 | btn_add_friend.setVisibility(View.VISIBLE);
61 | btn_chat.setVisibility(View.VISIBLE);
62 | }
63 | //构造聊天方的用户信息:传入用户id、用户名和用户头像三个参数
64 | info = new BmobIMUserInfo(user.getObjectId(),user.getUsername(),user.getAvatar());
65 | ImageLoaderFactory.getLoader().loadAvator(iv_avator,user.getAvatar(),R.mipmap.head);
66 | tv_name.setText(user.getUsername());
67 | }
68 |
69 | @OnClick(R.id.btn_add_friend)
70 | public void onAddClick(View view){
71 | sendAddFriendMessage();
72 | }
73 |
74 | /**
75 | * 发送添加好友的请求
76 | */
77 | private void sendAddFriendMessage(){
78 | //启动一个会话,如果isTransient设置为true,则不会创建在本地会话表中创建记录,
79 | //设置isTransient设置为false,则会在本地数据库的会话列表中先创建(如果没有)与该用户的会话信息,且将用户信息存储到本地的用户表中
80 | BmobIMConversation c = BmobIM.getInstance().startPrivateConversation(info, true,null);
81 | //这个obtain方法才是真正创建一个管理消息发送的会话
82 | BmobIMConversation conversation = BmobIMConversation.obtain(BmobIMClient.getInstance(), c);
83 | AddFriendMessage msg =new AddFriendMessage();
84 | User currentUser = BmobUser.getCurrentUser(this,User.class);
85 | msg.setContent("很高兴认识你,可以加个好友吗?");//给对方的一个留言信息
86 | Map map =new HashMap<>();
87 | map.put("name", currentUser.getUsername());//发送者姓名,这里只是举个例子,其实可以不需要传发送者的信息过去
88 | map.put("avatar",currentUser.getAvatar());//发送者的头像
89 | map.put("uid",currentUser.getObjectId());//发送者的uid
90 | msg.setExtraMap(map);
91 | conversation.sendMessage(msg, new MessageSendListener() {
92 | @Override
93 | public void done(BmobIMMessage msg, BmobException e) {
94 | if (e == null) {//发送成功
95 | toast("好友请求发送成功,等待验证");
96 | } else {//发送失败
97 | toast("发送失败:" + e.getMessage());
98 | }
99 | }
100 | });
101 | }
102 |
103 | @OnClick(R.id.btn_chat)
104 | public void onChatClick(View view){
105 | //启动一个会话,设置isTransient设置为false,则会在本地数据库的会话列表中先创建(如果没有)与该用户的会话信息,且将用户信息存储到本地的用户表中
106 | BmobIMConversation c = BmobIM.getInstance().startPrivateConversation(info,false,null);
107 | Bundle bundle = new Bundle();
108 | bundle.putSerializable("c", c);
109 | startActivity(ChatActivity.class, bundle, false);
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------