├── .gitignore ├── README.md ├── build.gradle ├── chatkitapplication ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── cn │ │ └── leancloud │ │ └── chatkitapplication │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── cn │ │ └── leancloud │ │ └── chatkitapplication │ │ ├── App.java │ │ ├── CustomUserProvider.java │ │ ├── LetterView.java │ │ ├── LoginActivity.java │ │ └── MainActivity.java │ └── res │ ├── layout │ ├── activity_login.xml │ ├── activity_main.xml │ └── tool_bar.xml │ ├── menu │ └── menu_square.xml │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── leancloudchatkit ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── cn │ │ └── leancloud │ │ └── chatkit │ │ ├── LCChatKit.java │ │ ├── LCChatKitUser.java │ │ ├── LCChatMessageInterface.java │ │ ├── LCChatProfileProvider.java │ │ ├── LCChatProfilesCallBack.java │ │ ├── activity │ │ ├── LCIMContactFragment.java │ │ ├── LCIMConversationActivity.java │ │ ├── LCIMConversationDetailActivity.java │ │ ├── LCIMConversationFragment.java │ │ ├── LCIMConversationListFragment.java │ │ ├── LCIMConversationSettingActivity.java │ │ ├── LCIMImageActivity.java │ │ └── LCIMUserSelectActivity.java │ │ ├── adapter │ │ ├── LCIMChatAdapter.java │ │ ├── LCIMCommonListAdapter.java │ │ └── LCIMMembersAdapter.java │ │ ├── cache │ │ ├── LCIMConversationItem.java │ │ ├── LCIMConversationItemCache.java │ │ ├── LCIMLocalCacheUtils.java │ │ ├── LCIMLocalStorage.java │ │ └── LCIMProfileCache.java │ │ ├── event │ │ ├── LCIMConnectionChangeEvent.java │ │ ├── LCIMConversationItemLongClickEvent.java │ │ ├── LCIMConversationReadStatusEvent.java │ │ ├── LCIMIMTypeMessageEvent.java │ │ ├── LCIMInputBottomBarEvent.java │ │ ├── LCIMInputBottomBarLocationClickEvent.java │ │ ├── LCIMInputBottomBarRecordEvent.java │ │ ├── LCIMInputBottomBarTextEvent.java │ │ ├── LCIMLocationItemClickEvent.java │ │ ├── LCIMMemberLetterEvent.java │ │ ├── LCIMMemberSelectedChangeEvent.java │ │ ├── LCIMMessageResendEvent.java │ │ ├── LCIMMessageUpdateEvent.java │ │ ├── LCIMMessageUpdatedEvent.java │ │ └── LCIMOfflineMessageCountChangeEvent.java │ │ ├── handler │ │ ├── ChatKitClientEventHandler.java │ │ ├── LCIMConversationHandler.java │ │ └── LCIMMessageHandler.java │ │ ├── utils │ │ ├── LCIMAudioHelper.java │ │ ├── LCIMConstants.java │ │ ├── LCIMConversationUtils.java │ │ ├── LCIMLogUtils.java │ │ ├── LCIMNotificationUtils.java │ │ ├── LCIMPathUtils.java │ │ └── LCIMSoftInputUtils.java │ │ ├── view │ │ ├── LCIMDividerItemDecoration.java │ │ ├── LCIMInputBottomBar.java │ │ ├── LCIMPlayButton.java │ │ └── LCIMRecordButton.java │ │ └── viewholder │ │ ├── LCIMChatHolderOption.java │ │ ├── LCIMChatItemAudioHolder.java │ │ ├── LCIMChatItemHolder.java │ │ ├── LCIMChatItemImageHolder.java │ │ ├── LCIMChatItemLocationHolder.java │ │ ├── LCIMChatItemTextHolder.java │ │ ├── LCIMCommonViewHolder.java │ │ ├── LCIMContactItemHolder.java │ │ └── LCIMConversationItemHolder.java │ └── res │ ├── drawable-xhdpi │ ├── lcim_bottom_bar_action_button_normal.png │ ├── lcim_bottom_bar_action_button_pressed.png │ ├── lcim_bottom_bar_camera_button_normal.png │ ├── lcim_bottom_bar_camera_button_pressed.png │ ├── lcim_bottom_bar_keyboard_button_normal.png │ ├── lcim_bottom_bar_keyboard_button_pressed.png │ ├── lcim_bottom_bar_location_button_normal.png │ ├── lcim_bottom_bar_location_button_pressed.png │ ├── lcim_bottom_bar_picture_button_normal.png │ ├── lcim_bottom_bar_picture_button_pressed.png │ ├── lcim_bottom_bar_send_button_normal.png │ ├── lcim_bottom_bar_send_button_pressed.png │ ├── lcim_bottom_bar_voice_button_normal.png │ ├── lcim_bottom_bar_voice_button_pressed.png │ ├── lcim_chat_icon_voice0.png │ ├── lcim_chat_icon_voice1.png │ ├── lcim_chat_icon_voice2.png │ ├── lcim_chat_icon_voice3.png │ ├── lcim_chat_icon_voice4.png │ ├── lcim_chat_icon_voice5.png │ ├── lcim_chat_item_left_bg.9.png │ ├── lcim_chat_item_location_default.9.png │ ├── lcim_chat_item_right_bg.9.png │ ├── lcim_chat_resend_normal.png │ ├── lcim_chat_resend_pressed.png │ ├── lcim_chat_top_voice_bg.9.png │ ├── lcim_chat_voice_bg.9.png │ ├── lcim_chat_voice_bg_pressed.9.png │ ├── lcim_chat_voice_left.png │ ├── lcim_chat_voice_left1.png │ ├── lcim_chat_voice_left2.png │ ├── lcim_chat_voice_left3.png │ ├── lcim_chat_voice_right.png │ ├── lcim_chat_voice_right1.png │ ├── lcim_chat_voice_right2.png │ ├── lcim_chat_voice_right3.png │ ├── lcim_default_avatar_icon.png │ ├── lcim_group_icon.png │ ├── lcim_record_icon_voice0.png │ ├── lcim_record_icon_voice1.png │ ├── lcim_record_icon_voice2.png │ ├── lcim_record_icon_voice3.png │ ├── lcim_record_icon_voice4.png │ └── lcim_record_icon_voice5.png │ ├── drawable │ ├── ic_info_black_24dp.xml │ ├── ic_notifications_black_24dp.xml │ ├── ic_sync_black_24dp.xml │ ├── lcim_bottom_bar_action_button_bg.xml │ ├── lcim_bottom_bar_camera_button_bg.xml │ ├── lcim_bottom_bar_keyboard_button_bg.xml │ ├── lcim_bottom_bar_location_button_bg.xml │ ├── lcim_bottom_bar_picture_button_bg.xml │ ├── lcim_bottom_bar_send_button_bg.xml │ ├── lcim_bottom_bar_voice_button_bg.xml │ ├── lcim_chat_anim_voice_left.xml │ ├── lcim_chat_anim_voice_right.xml │ ├── lcim_chat_record_button_round_background.xml │ ├── lcim_chat_resend_bg.xml │ ├── lcim_read_badge.xml │ └── lcim_textview_bg.xml │ ├── layout │ ├── activity_conversation_detail.xml │ ├── common_user_item.xml │ ├── contact_fragment.xml │ ├── lcim_bottom_bar_action_layout.xml │ ├── lcim_bottom_bar_more_layout.xml │ ├── lcim_bottom_bar_text_layout.xml │ ├── lcim_chat_image_brower_layout.xml │ ├── lcim_chat_input_bottom_bar_layout.xml │ ├── lcim_chat_item_image_layout.xml │ ├── lcim_chat_item_left_audio_layout.xml │ ├── lcim_chat_item_left_layout.xml │ ├── lcim_chat_item_left_text_layout.xml │ ├── lcim_chat_item_location.xml │ ├── lcim_chat_item_right_audio_layout.xml │ ├── lcim_chat_item_right_layout.xml │ ├── lcim_chat_item_right_text_layout.xml │ ├── lcim_chat_record_layout.xml │ ├── lcim_common_footer_item_layout.xml │ ├── lcim_common_header_item_layout.xml │ ├── lcim_contact_activity.xml │ ├── lcim_conversation_activity.xml │ ├── lcim_conversation_fragment.xml │ ├── lcim_conversation_item.xml │ ├── lcim_conversation_list_fragment.xml │ ├── lcim_conversation_setting.xml │ └── lcim_load_more_footer_layout.xml │ ├── menu │ ├── conv_member_menu.xml │ ├── conv_menu.xml │ └── menu_setting.xml │ ├── values │ ├── lcim_attrs.xml │ ├── lcim_colors.xml │ ├── lcim_dimens.xml │ ├── lcim_strings.xml │ ├── lcim_styles.xml │ └── strings.xml │ └── xml │ └── file_paths.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # ADT 16 | .classpath 17 | .project 18 | .settings 19 | local.properties 20 | bin 21 | gen 22 | _layouts 23 | proguard.cfg 24 | 25 | # OSX 26 | .DS_Store 27 | 28 | # Gradle files 29 | .gradle/ 30 | build/ 31 | 32 | # Local configuration file (sdk path, etc) 33 | local.properties 34 | 35 | # Proguard folder generated by Eclipse 36 | proguard/ 37 | 38 | # IDEA 39 | *.iml 40 | *.ipr 41 | *.iws 42 | out 43 | .idea 44 | 45 | # Maven 46 | target 47 | release.properties 48 | pom.xml.* 49 | 50 | # VIM 51 | *~ 52 | *.swp 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ChatKit 2 | 3 | ChatKit 是由 LeanCloud 官方推出的、基于 [LeanCloud 实时通信 SDK「LeanMessage」](https://leancloud.cn/docs/realtime_v2.html) 开发并封装了简单 UI 的聊天套件。它可以帮助开发者快速掌握 LeanMessage 的技术细节,轻松扩展和实现常用的聊天功能。 4 | 5 | ChatKit 是一个免费且开源的项目组件,提供完全自由的授权协议,开发者可以对其进行任意的自定义和二次封装。ChatKit 的底层依然基于 LeanCloud 为各平台推出的 SDK,其最大特点是把聊天常用的一些功能配合 UI 一起提供给开发者。 6 | 7 | 使用方法请参考[官方文档](https://leancloud.cn/docs/chatkit-android.html)。 8 | 9 | ## 普通聊天消息 10 | LeanCloud 即时通讯支持发送普通的文本、图片、音频、视频、文件和地理位置消息,支持直接发送二进制消息,并且还支持开发者扩展自己的消息类型。我们支持单聊、群聊、不限人数的开放聊天室,以及临时聊天室和系统对话(公众账号)。与其他 IM 服务不同的是,LeanCloud 即时通讯服务提供给你最大的灵活性和自由度,包括: 11 | 1. 内嵌离线推送与消息同步机制,可以保证离线消息以最快速度下发到客户端; 12 | 2. 支持多设备同时登录,且允许开发者自由选择合适的多点登录模式; 13 | 3. 支持第三方服务端进行安全签名与权限控制; 14 | 4. 消息生命周期的全过程都支持第三方 hook 函数,允许业务方进行深度定制; 15 | 5. 开放 API 可以在第三方服务端进行更多操作; 16 | 17 | 具体可以参考我们的开发指南: 18 | 1. [从简单的单聊、群聊、收发图文消息开始](https://leancloud.cn/docs/realtime-guide-beginner.html) 19 | 2. [消息收发的更多方式,离线推送与消息同步,多设备登录](https://leancloud.cn/docs/realtime-guide-intermediate.html) 20 | 3. [安全与签名、黑名单和权限管理、玩转聊天室和临时对话](https://leancloud.cn/docs/realtime-guide-senior.html) 21 | 4. [详解消息 hook 与系统对话,打造自己的聊天机器人](https://leancloud.cn/docs/realtime-guide-systemconv.html) 22 | 23 | ## 实时音视频聊天 24 | LeanCloud 与声网是深度合作伙伴,推荐开发者接入声网 SDK 实现实时音视频通讯功能。 25 | 本 Demo 已经做了集成(参见分支:https://github.com/leancloud/LeanCloudChatKit-Android/tree/agora ),希望可以给大家提供一些参考价值。 26 | 27 | -------------------------------------------------------------------------------- /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 | google() 6 | jcenter() 7 | mavenLocal() 8 | maven { 9 | url "https://oss.sonatype.org/content/repositories/snapshots/" 10 | } 11 | } 12 | dependencies { 13 | classpath 'com.android.tools.build:gradle:3.5.3' 14 | 15 | // NOTE: Do not place your application dependencies here; they belong 16 | // in the individual module build.gradle files 17 | } 18 | } 19 | 20 | allprojects { 21 | repositories { 22 | google() 23 | jcenter() 24 | mavenLocal() 25 | maven { 26 | url "https://oss.sonatype.org/content/repositories/snapshots/" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /chatkitapplication/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | buildToolsVersion "28.0.3" 6 | 7 | defaultConfig { 8 | applicationId "cn.leancloud.imkitapplication" 9 | minSdkVersion 14 10 | targetSdkVersion 26 11 | versionCode 1 12 | versionName "1.0" 13 | multiDexEnabled true 14 | } 15 | 16 | lintOptions { 17 | abortOnError false 18 | } 19 | 20 | compileOptions { 21 | sourceCompatibility JavaVersion.VERSION_1_8 22 | targetCompatibility JavaVersion.VERSION_1_8 23 | } 24 | 25 | buildTypes { 26 | release { 27 | minifyEnabled true 28 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 29 | } 30 | } 31 | } 32 | 33 | dependencies { 34 | 35 | implementation project(':leancloudchatkit') 36 | implementation('cn.leancloud:realtime-android:8.2.9') { 37 | exclude group: 'cn.leancloud', module: 'realtime-core' 38 | } 39 | implementation('cn.leancloud:storage-android:8.2.9') { 40 | exclude group: 'cn.leancloud', module: 'realtime-core' 41 | } 42 | implementation ('cn.leancloud:realtime-core:8.2.9') 43 | // implementation('cn.leancloud:storage-core:8.2.9') { 44 | // exclude group: 'com.squareup.okhttp3', module: 'okhttp' 45 | // } 46 | // 47 | // implementation("com.squareup.okhttp3:okhttp:3.14.9") // just test for okhttp 3.x 48 | implementation 'io.reactivex.rxjava2:rxandroid:2.1.0' 49 | 50 | implementation 'com.squareup.picasso:picasso:2.5.2' 51 | implementation 'de.greenrobot:eventbus:2.4.0' 52 | 53 | implementation 'com.google.android.material:material:1.0.0' 54 | implementation 'com.github.stuxuhai:jpinyin:1.0' 55 | } 56 | -------------------------------------------------------------------------------- /chatkitapplication/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # proguard 2 | 3 | # ------------------------ leancloud sdk ------------------------ 4 | -keepattributes Signature 5 | -dontwarn com.jcraft.jzlib.** 6 | -keep class com.jcraft.jzlib.** { *;} 7 | 8 | -dontwarn sun.misc.** 9 | -keep class sun.misc.** { *;} 10 | 11 | -dontwarn com.alibaba.fastjson.** 12 | -dontnote com.alibaba.fastjson.** 13 | -keep class com.alibaba.fastjson.** { *;} 14 | 15 | -dontwarn sun.security.** 16 | -keep class sun.security.** { *; } 17 | 18 | -dontwarn com.google.** 19 | -keep class com.google.** { *;} 20 | 21 | -dontwarn com.avos.** 22 | -dontnote com.avos.** 23 | -keep class com.avos.** { *;} 24 | 25 | -keep public class android.net.http.SslError 26 | -keep public class android.webkit.WebViewClient 27 | 28 | -dontwarn android.webkit.WebView 29 | -dontwarn android.net.http.SslError 30 | -dontwarn android.webkit.WebViewClient 31 | -dontnote android.net.http.** 32 | 33 | -dontwarn android.support.** 34 | 35 | -dontwarn org.apache.** 36 | -dontnote org.apache.** 37 | -keep class org.apache.** { *;} 38 | 39 | -dontwarn org.jivesoftware.smack.** 40 | -keep class org.jivesoftware.smack.** { *;} 41 | 42 | -dontwarn com.loopj.** 43 | -keep class com.loopj.** { *;} 44 | 45 | -dontwarn com.squareup.okhttp.** 46 | -keep class com.squareup.okhttp.** { *;} 47 | -keep interface com.squareup.okhttp.** { *; } 48 | 49 | -dontwarn okio.** 50 | 51 | -keep class com.google.protobuf.** { *; } 52 | -keep public class * extends com.google.protobuf.** { *; } 53 | -dontwarn com.google.protobuf.** 54 | 55 | -dontwarn org.xbill.** 56 | -keep class org.xbill.** { *;} 57 | 58 | -keepattributes *Annotation* 59 | 60 | 61 | # ------------------------ ChatKit ------------------------ 62 | -dontwarn cn.leancloud.chatkit.** 63 | -keep class cn.leancloud.chatkit.** { *;} 64 | -dontnote cn.leancloud.chatkit.** 65 | 66 | # ------------------------ picasso ------------------------ 67 | -dontwarn com.squareup.picasso** 68 | -keep class com.squareup.picasso.**{*;} 69 | 70 | # ------------------------ eventbus ------------------------ 71 | -keepclassmembers class ** { 72 | public void onEvent*(**); 73 | } 74 | 75 | -keepattributes *Annotation* 76 | -keepclassmembers class ** { 77 | @org.greenrobot.eventbus.Subscribe ; 78 | } 79 | -keep enum org.greenrobot.eventbus.ThreadMode { *; } 80 | 81 | -dontnote org.greenrobot.eventbus.* -------------------------------------------------------------------------------- /chatkitapplication/src/androidTest/java/cn/leancloud/chatkitapplication/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package cn.leancloud.chatkitapplication; 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 | } -------------------------------------------------------------------------------- /chatkitapplication/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /chatkitapplication/src/main/java/cn/leancloud/chatkitapplication/App.java: -------------------------------------------------------------------------------- 1 | package cn.leancloud.chatkitapplication; 2 | 3 | import android.app.Application; 4 | import android.app.NotificationManager; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.util.Log; 8 | import android.widget.Toast; 9 | 10 | import cn.leancloud.cache.PersistenceUtil; 11 | 12 | import java.io.File; 13 | 14 | import cn.leancloud.*; 15 | import cn.leancloud.callback.SaveCallback; 16 | import cn.leancloud.im.LCIMOptions; 17 | import cn.leancloud.im.v2.*; 18 | import cn.leancloud.im.v2.callback.*; 19 | import cn.leancloud.push.PushService; 20 | 21 | import cn.leancloud.chatkit.LCChatKit; 22 | import io.reactivex.Observer; 23 | import io.reactivex.disposables.Disposable; 24 | 25 | /** 26 | * Created by wli on 16/2/24. 27 | */ 28 | public class App extends Application { 29 | 30 | // 此 id 与 key 仅供测试使用 31 | private final String APP_ID = "dYRQ8YfHRiILshUnfFJu2eQM-gzGzoHsz"; 32 | private final String APP_KEY = "ye24iIK6ys8IvaISMC4Bs5WK"; 33 | 34 | @Override 35 | public void onCreate() { 36 | super.onCreate(); 37 | Log.i(App.class.getSimpleName(), "App#onCreate()"); 38 | 39 | LCChatKit.getInstance().setProfileProvider(CustomUserProvider.getInstance()); 40 | LeanCloud.setLogLevel(LCLogger.Level.DEBUG); 41 | // AVOSCloud.useAVCloudUS(); 42 | LCIMOptions.getGlobalOptions().setDisableAutoLogin4Push(true); 43 | LCChatKit.getInstance().init(getApplicationContext(), APP_ID, APP_KEY, "https://dyrq8yfh.lc-cn-n1-shared.com"); 44 | 45 | PushService.setDefaultPushCallback(this, MainActivity.class); 46 | PushService.setAutoWakeUp(true); 47 | PushService.setDefaultChannelId(this, "default"); 48 | 49 | LCInstallation.getCurrentInstallation().saveInBackground().subscribe(new Observer() { 50 | @Override 51 | public void onSubscribe(Disposable d) { 52 | 53 | } 54 | 55 | @Override 56 | public void onNext(LCObject abject) { 57 | String installationId = LCInstallation.getCurrentInstallation().getInstallationId(); 58 | System.out.println("--- " + installationId); 59 | } 60 | 61 | @Override 62 | public void onError(Throwable e) { 63 | // 保存失败,输出错误信息 64 | System.out.println("failed to save installation."); 65 | } 66 | 67 | @Override 68 | public void onComplete() { 69 | 70 | } 71 | }); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /chatkitapplication/src/main/java/cn/leancloud/chatkitapplication/CustomUserProvider.java: -------------------------------------------------------------------------------- 1 | package cn.leancloud.chatkitapplication; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import cn.leancloud.chatkit.LCChatKitUser; 7 | import cn.leancloud.chatkit.LCChatProfileProvider; 8 | import cn.leancloud.chatkit.LCChatProfilesCallBack; 9 | 10 | /** 11 | * Created by wli on 15/12/4. 12 | * 实现自定义用户体系 13 | */ 14 | public class CustomUserProvider implements LCChatProfileProvider { 15 | 16 | private static CustomUserProvider customUserProvider; 17 | 18 | public synchronized static CustomUserProvider getInstance() { 19 | if (null == customUserProvider) { 20 | customUserProvider = new CustomUserProvider(); 21 | } 22 | return customUserProvider; 23 | } 24 | 25 | private CustomUserProvider() { 26 | } 27 | 28 | private static List partUsers = new ArrayList(); 29 | 30 | // 此数据均为 fake,仅供参考 31 | static { 32 | partUsers.add(new LCChatKitUser("Tom", "Tom", "http://www.avatarsdb.com/avatars/tom_and_jerry2.jpg")); 33 | partUsers.add(new LCChatKitUser("Jerry", "Jerry", "http://www.avatarsdb.com/avatars/jerry.jpg")); 34 | partUsers.add(new LCChatKitUser("Harry", "Harry", "http://www.avatarsdb.com/avatars/young_harry.jpg")); 35 | partUsers.add(new LCChatKitUser("William", "William", "http://www.avatarsdb.com/avatars/william_shakespeare.jpg")); 36 | partUsers.add(new LCChatKitUser("Bob", "Bob", "http://www.avatarsdb.com/avatars/bath_bob.jpg")); 37 | } 38 | 39 | @Override 40 | public void fetchProfiles(List list, LCChatProfilesCallBack callBack) { 41 | List userList = new ArrayList(); 42 | for (String userId : list) { 43 | for (LCChatKitUser user : partUsers) { 44 | if (user.getUserId().equals(userId)) { 45 | userList.add(user); 46 | break; 47 | } 48 | } 49 | } 50 | callBack.done(userList, null); 51 | } 52 | 53 | @Override 54 | public List getAllUsers() { 55 | return partUsers; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /chatkitapplication/src/main/java/cn/leancloud/chatkitapplication/LetterView.java: -------------------------------------------------------------------------------- 1 | package cn.leancloud.chatkitapplication; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.MotionEvent; 6 | import android.view.View; 7 | import android.widget.LinearLayout; 8 | import android.widget.TextView; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | import cn.leancloud.chatkit.event.LCIMMemberLetterEvent; 13 | import de.greenrobot.event.EventBus; 14 | 15 | 16 | /** 17 | * Created by wli on 15/8/24. 18 | * 联系人列表,快速滑动字母导航 View 19 | * 此处仅在滑动或点击时发送 LCIMMemberLetterEvent,接收放自己处理相关逻辑 20 | * 注意:因为长按事件等触发,有可能重复发送 21 | */ 22 | public class LetterView extends LinearLayout { 23 | 24 | public LetterView(Context context) { 25 | super(context); 26 | setOrientation(VERTICAL); 27 | updateLetters(); 28 | } 29 | 30 | public LetterView(Context context, AttributeSet attrs) { 31 | super(context, attrs); 32 | setOrientation(VERTICAL); 33 | updateLetters(); 34 | } 35 | 36 | private void updateLetters() { 37 | setLetters(getSortLetters()); 38 | } 39 | 40 | /** 41 | * 设置快速滑动的字母集合 42 | */ 43 | public void setLetters(List letters) { 44 | removeAllViews(); 45 | for(Character content : letters) { 46 | TextView view = new TextView(getContext()); 47 | LinearLayout.LayoutParams param = new LinearLayout.LayoutParams( 48 | LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, 1.0f); 49 | view.setLayoutParams(param); 50 | view.setText(content.toString()); 51 | addView(view); 52 | } 53 | 54 | setOnTouchListener(new OnTouchListener() { 55 | @Override 56 | public boolean onTouch(View v, MotionEvent event) { 57 | int x = Math.round(event.getX()); 58 | int y = Math.round(event.getY()); 59 | for (int i = 0; i < getChildCount(); i++) { 60 | TextView child = (TextView) getChildAt(i); 61 | if (y > child.getTop() && y < child.getBottom()) { 62 | LCIMMemberLetterEvent letterEvent = new LCIMMemberLetterEvent(); 63 | letterEvent.letter = child.getText().toString().charAt(0); 64 | EventBus.getDefault().post(letterEvent); 65 | } 66 | } 67 | return true; 68 | } 69 | }); 70 | } 71 | 72 | /** 73 | * 默认的只包含 A-Z 的字母 74 | */ 75 | private List getSortLetters() { 76 | List letterList = new ArrayList(); 77 | for (char c = 'A'; c <= 'Z'; c++) { 78 | letterList.add(c); 79 | } 80 | return letterList; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /chatkitapplication/src/main/java/cn/leancloud/chatkitapplication/LoginActivity.java: -------------------------------------------------------------------------------- 1 | package cn.leancloud.chatkitapplication; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import androidx.appcompat.app.AppCompatActivity; 6 | import android.text.TextUtils; 7 | import android.view.View; 8 | import android.widget.Button; 9 | import android.widget.EditText; 10 | import android.widget.Toast; 11 | 12 | import cn.leancloud.im.LCIMOptions; 13 | import cn.leancloud.im.v2.LCIMClient; 14 | import cn.leancloud.im.v2.LCIMException; 15 | import cn.leancloud.im.v2.callback.LCIMClientCallback; 16 | 17 | import cn.leancloud.chatkit.LCChatKit; 18 | 19 | /** 20 | * 登陆页面 21 | */ 22 | public class LoginActivity extends AppCompatActivity { 23 | 24 | protected EditText nameView; 25 | protected Button loginButton; 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_login); 31 | 32 | nameView = (EditText) findViewById(R.id.activity_login_et_username); 33 | loginButton = (Button) findViewById(R.id.activity_login_btn_login); 34 | loginButton.setOnClickListener(new View.OnClickListener() { 35 | @Override 36 | public void onClick(View v) { 37 | onLoginClick(); 38 | } 39 | }); 40 | } 41 | 42 | public void onLoginClick() { 43 | String clientId = nameView.getText().toString(); 44 | if (TextUtils.isEmpty(clientId.trim())) { 45 | Toast.makeText(this, "不能为空", Toast.LENGTH_SHORT).show(); 46 | return; 47 | } 48 | 49 | LCIMOptions.getGlobalOptions().setAutoOpen(true); 50 | LCChatKit.getInstance().open(clientId, new LCIMClientCallback() { 51 | @Override 52 | public void done(LCIMClient LCIMClient, LCIMException e) { 53 | if (null == e) { 54 | Intent intent = new Intent(LoginActivity.this, MainActivity.class); 55 | startActivity(intent); 56 | } else { 57 | Toast.makeText(LoginActivity.this, e.toString(), Toast.LENGTH_SHORT).show(); 58 | } 59 | } 60 | }); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /chatkitapplication/src/main/res/layout/activity_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 19 | 20 |