即时通讯的依赖
1 compile files('libs/nim-basesdk-4.5.1.jar') 2 compile files('libs/nim-chatroom-4.5.1.jar') 3 compile 'com.android.support:appcompat-v7:26.+' 4 compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha8' 5 testCompile 'junit:junit:4.12' 6 compile 'com.jakewharton:butterknife:8.8.1' 7 annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
即时通讯使用云信权限
1 <!-- 权限声明 --> 2 <!-- 访问网络状态 --> 3 <uses-permission android:name="android.permission.INTERNET" /> 4 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 5 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 6 <!-- 控制呼吸灯,振动器等,用于新消息提醒 --> 7 <uses-permission android:name="android.permission.FLASHLIGHT" /> 8 <uses-permission android:name="android.permission.VIBRATE" /> 9 <!-- 外置存储存取权限 --> 10 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 11 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 12 13 <!-- 多媒体相关 --> 14 <uses-permission android:name="android.permission.CAMERA" /> 15 <uses-permission android:name="android.permission.RECORD_AUDIO" /> 16 <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 17 18 <!-- 如果需要实时音视频通话模块,下面的权限也是必须的。否则,可以不加 --> 19 <uses-permission android:name="android.permission.BLUETOOTH" /> 20 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 21 <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> 22 <uses-permission android:name="android.permission.BROADCAST_STICKY" /> 23 24 <uses-feature android:name="android.hardware.camera" /> 25 <uses-feature android:name="android.hardware.camera.autofocus" /> 26 <uses-feature 27 android:glEsVersion="0x00020000" 28 android:required="true" /> 29 30 <!-- SDK 权限申明, 第三方 APP 接入时,请将 com.netease.nim.demo 替换为自己的包名 --> 31 <!-- 和下面的 uses-permission 一起加入到你的 AndroidManifest 文件中。 --> 32 <permission 33 android:name="lipengfei.xunxin.permission.RECEIVE_MSG" 34 android:protectionLevel="signature" /> 35 <!-- 接收 SDK 消息广播权限, 第三方 APP 接入时,请将 com.netease.nim.demo 替换为自己的包名 --> 36 <uses-permission android:name="lipengfei.xunxin.permission.RECEIVE_MSG" />
在清单中application中activity之前加入app的key
1 <!-- 2 APP key, 可以在这里设置,也可以在 SDKOptions 中提供。 3 如果 SDKOptions 中提供了,取 SDKOptions 中的值。 4 --> 5 <meta-data 6 android:name="com.netease.nim.appKey" 7 android:value="6619d22be8ecc9e84ce7c64c99c8c4d9" /> 8 9 <!-- 云信后台服务,请使用独立进程。 --> 10 <service 11 android:name="com.netease.nimlib.service.NimService" 12 android:process=":core" /> 13 14 <!-- 云信后台辅助服务 --> 15 <service 16 android:name="com.netease.nimlib.service.NimService$Aux" 17 android:process=":core" /> 18 19 <!-- 云信后台辅助服务 --> 20 <service 21 android:name="com.netease.nimlib.job.NIMJobService" 22 android:exported="true" 23 android:permission="android.permission.BIND_JOB_SERVICE" 24 android:process=":core" /> 25 26 <!-- 云信监视系统启动和网络变化的广播接收器,保持和 NimService 同一进程 --> 27 <receiver 28 android:name="com.netease.nimlib.service.NimReceiver" 29 android:exported="false" 30 android:process=":core"> 31 <intent-filter> 32 <action android:name="android.intent.action.BOOT_COMPLETED" /> 33 <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> 34 </intent-filter> 35 </receiver> 36 37 <!-- 云信进程间通信 Receiver --> 38 <receiver android:name="com.netease.nimlib.service.ResponseReceiver" /> 39 40 <!-- 云信进程间通信service --> 41 <service android:name="com.netease.nimlib.service.ResponseService" /> 42 43 <!-- 云信进程间通信provider --> 44 <!-- android:authorities="{包名}.ipc.provider", 请将com.netease.nim.demo替换为自己的包名 --> 45 <provider 46 android:name="com.netease.nimlib.ipc.NIMContentProvider" 47 android:authorities="lipengfei.xunxin.ipc.provider" 48 android:exported="false" 49 android:process=":core" />
使用云信SDK的方法
1 import android.app.Application; 2 import android.graphics.Bitmap; 3 import android.graphics.Color; 4 import android.os.Environment; 5 import com.netease.nimlib.sdk.NIMClient; 6 import com.netease.nimlib.sdk.SDKOptions; 7 import com.netease.nimlib.sdk.StatusBarNotificationConfig; 8 import com.netease.nimlib.sdk.auth.LoginInfo; 9 import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum; 10 import com.netease.nimlib.sdk.uinfo.UserInfoProvider; 11 import com.netease.nimlib.sdk.uinfo.model.UserInfo; 12 13 public class MyApp extends Application{ 14 @Override 15 public void onCreate() { 16 super.onCreate(); 17 NIMClient.init(this, loginInfo(), options()); 18 19 } 20 private SDKOptions options() { 21 SDKOptions options = new SDKOptions(); 22 23 // 如果将新消息通知提醒托管给 SDK 完成,需要添加以下配置。否则无需设置。 24 StatusBarNotificationConfig config = new StatusBarNotificationConfig(); 25 // 呼吸灯配置 26 config.ledARGB = Color.GREEN; 27 config.ledOnMs = 1000; 28 config.ledOffMs = 1500; 29 // 通知铃声的uri字符串 30 config.notificationSound = "android.resource://com.netease.nim.demo/raw/msg"; 31 options.statusBarNotificationConfig = config; 32 33 // 配置保存图片,文件,log 等数据的目录 34 // 如果 options 中没有设置这个值,SDK 会使用下面代码示例中的位置作为 SDK 的数据目录。 35 // 该目录目前包含 log, file, image, audio, video, thumb 这6个目录。 36 // 如果第三方 APP 需要缓存清理功能, 清理这个目录下面个子目录的内容即可。 37 String sdkPath = Environment.getExternalStorageDirectory() + "/" + getPackageName() + "/nim"; 38 options.sdkStorageRootPath = sdkPath; 39 40 // 配置是否需要预下载附件缩略图,默认为 true 41 options.preloadAttach = true; 42 43 // 配置附件缩略图的尺寸大小。表示向服务器请求缩略图文件的大小 44 // 该值一般应根据屏幕尺寸来确定, 默认值为 Screen.width / 2 45 options.thumbnailSize = 480 / 2; 46 47 // 用户资料提供者, 目前主要用于提供用户资料,用于新消息通知栏中显示消息来源的头像和昵称 48 options.userInfoProvider = new UserInfoProvider() { 49 @Override 50 public UserInfo getUserInfo(String account) { 51 return null; 52 } 53 54 55 public int getDefaultIconResId() { 56 return R.mipmap.ic_launcher; 57 } 58 59 60 public Bitmap getTeamIcon(String tid) { 61 return null; 62 } 63 64 65 public Bitmap getAvatarForMessageNotifier(String account) { 66 return null; 67 } 68 69 @Override 70 public String getDisplayNameForMessageNotifier(String account, String sessionId, 71 SessionTypeEnum sessionType) { 72 return null; 73 } 74 75 @Override 76 public Bitmap getAvatarForMessageNotifier(SessionTypeEnum sessionTypeEnum, String s) { 77 return null; 78 } 79 }; 80 return options; 81 } 82 // 如果已经存在用户登录信息,返回LoginInfo,否则返回null即可 83 private LoginInfo loginInfo() { 84 return null; 85 } 86 87 88 }
登录通讯的布局
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 xmlns:app="http://schemas.android.com/apk/res-auto" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 tools:context="lipengfei.xunxin.MainActivity"> 9 10 <EditText 11 android:id="@+id/et_id" 12 android:layout_width="match_parent" 13 android:layout_height="wrap_content" 14 android:hint="请输入账号" 15 android:layout_margin="10dp"/> 16 <EditText 17 android:id="@+id/et_pass" 18 android:layout_width="match_parent" 19 android:layout_height="wrap_content" 20 android:hint="请输入密码" 21 android:layout_margin="10dp" 22 android:layout_below="@id/et_id"/> 23 24 <LinearLayout 25 android:layout_width="match_parent" 26 android:layout_height="wrap_content" 27 android:orientation="horizontal" 28 android:layout_below="@id/et_pass"> 29 <Button 30 android:id="@+id/btn1" 31 android:layout_width="0dp" 32 android:layout_height="wrap_content" 33 android:layout_weight="1" 34 android:text="登录"/> 35 <Button 36 android:layout_width="0dp" 37 android:layout_height="wrap_content" 38 android:layout_weight="1" 39 android:text="注册"/> 40 </LinearLayout> 41 42 </RelativeLayout>
登录通讯的代码实现
1 import android.content.Intent; 2 import android.os.Bundle; 3 import android.support.v7.app.AppCompatActivity; 4 import android.widget.Button; 5 import android.widget.EditText; 6 import android.widget.Toast; 7 import com.netease.nimlib.sdk.NIMClient; 8 import com.netease.nimlib.sdk.RequestCallback; 9 import com.netease.nimlib.sdk.auth.AuthService; 10 import com.netease.nimlib.sdk.auth.LoginInfo; 11 import butterknife.BindView; 12 import butterknife.ButterKnife; 13 import butterknife.OnClick; 14 15 public class MainActivity extends AppCompatActivity { 16 17 @BindView(R.id.et_id) 18 EditText etId; 19 @BindView(R.id.et_pass) 20 EditText etPass; 21 @BindView(R.id.btn1) 22 Button btn1; 23 24 @Override 25 protected void onCreate(Bundle savedInstanceState) { 26 super.onCreate(savedInstanceState); 27 setContentView(R.layout.activity_main); 28 ButterKnife.bind(this); 29 } 30 31 @OnClick(R.id.btn1) 32 public void onViewClicked() { 33 LoginInfo info=new LoginInfo(etId.getText().toString(),etPass.getText().toString()); 34 RequestCallback<LoginInfo> callback=new RequestCallback<LoginInfo>() { 35 @Override 36 public void onSuccess(LoginInfo loginInfo) { 37 Toast.makeText(MainActivity.this, "登录成功!!!", Toast.LENGTH_SHORT).show(); 38 startActivity(new Intent(MainActivity.this,Main2Activity.class)); 39 finish(); 40 } 41 42 @Override 43 public void onFailed(int i) { 44 Toast.makeText(MainActivity.this, "登录失败!!!", Toast.LENGTH_SHORT).show(); 45 } 46 47 @Override 48 public void onException(Throwable throwable) { 49 50 } 51 }; 52 NIMClient.getService(AuthService.class).login(info).setCallback(callback); 53 } 54 }
单人聊天布局
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 android:orientation="vertical" 8 tools:context="lipengfei.xunxin.Main2Activity"> 9 <TextView 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:layout_gravity="center_horizontal" 13 android:background="@android:color/holo_green_light" 14 android:gravity="center" 15 android:paddingBottom="10dp" 16 android:paddingTop="10dp" 17 android:text="单聊" 18 android:textColor="@android:color/white" 19 android:textSize="20sp" /> 20 21 <LinearLayout 22 android:layout_width="match_parent" 23 android:layout_height="0dp" 24 android:layout_weight="1" 25 android:orientation="vertical" 26 android:paddingLeft="20dp" 27 android:paddingRight="20dp"> 28 29 <TextView 30 android:layout_width="wrap_content" 31 android:layout_height="wrap_content" 32 android:text="收到的消息:" /> 33 34 <TextView 35 android:id="@+id/tv_recivetv_in" 36 android:layout_width="wrap_content" 37 android:layout_height="0dp" 38 android:layout_weight="1" 39 android:text="1111" 40 android:textColor="@android:color/holo_red_light" /> 41 42 <TextView 43 android:layout_width="wrap_content" 44 android:layout_height="wrap_content" 45 android:text="发出的消息:" /> 46 47 <TextView 48 android:id="@+id/tv_send_out" 49 android:layout_width="wrap_content" 50 android:layout_height="0dp" 51 android:layout_weight="1" 52 android:text="2222" 53 android:textColor="@android:color/holo_blue_light" /> 54 </LinearLayout> 55 56 <EditText 57 android:id="@+id/et_input" 58 android:layout_width="match_parent" 59 android:layout_height="wrap_content" 60 android:layout_marginLeft="20dp" 61 android:layout_marginRight="20dp" 62 android:layout_marginTop="5dp" 63 android:hint="输入消息..." /> 64 65 <LinearLayout 66 android:layout_width="match_parent" 67 android:layout_height="wrap_content" 68 android:orientation="horizontal" 69 android:paddingLeft="10dp" 70 android:paddingRight="10dp"> 71 72 <Button 73 android:id="@+id/btn_select_people" 74 android:layout_width="0dp" 75 android:layout_height="wrap_content" 76 android:layout_weight="1" 77 android:text="选择联系人" /> 78 79 <Button 80 android:id="@+id/btn_send" 81 android:layout_width="0dp" 82 android:layout_height="wrap_content" 83 android:layout_weight="1" 84 android:text="发送" /> 85 86 <Button 87 android:id="@+id/btn_out" 88 android:layout_width="0dp" 89 android:layout_height="wrap_content" 90 android:layout_weight="1" 91 android:text="退出" /> 92 </LinearLayout> 93 94 </LinearLayout>
单人聊天代码实现
1 import android.content.Intent; 2 import android.os.Bundle; 3 import android.support.v7.app.AppCompatActivity; 4 import android.view.View; 5 import android.widget.Button; 6 import android.widget.EditText; 7 import android.widget.TextView; 8 import com.netease.nimlib.sdk.NIMClient; 9 import com.netease.nimlib.sdk.Observer; 10 import com.netease.nimlib.sdk.auth.AuthService; 11 import com.netease.nimlib.sdk.msg.MessageBuilder; 12 import com.netease.nimlib.sdk.msg.MsgService; 13 import com.netease.nimlib.sdk.msg.MsgServiceObserve; 14 import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum; 15 import com.netease.nimlib.sdk.msg.model.IMMessage; 16 17 import java.util.List; 18 19 import butterknife.BindView; 20 import butterknife.ButterKnife; 21 import butterknife.OnClick; 22 23 public class Main2Activity extends AppCompatActivity { 24 private String account="z000002"; 25 private Observer<List<IMMessage>> observer; 26 @BindView(R.id.tv_recivetv_in) 27 TextView tvRecivetvIn; 28 @BindView(R.id.tv_send_out) 29 TextView tvSendOut; 30 @BindView(R.id.et_input) 31 EditText etInput; 32 @BindView(R.id.btn_select_people) 33 Button btnSelectPeople; 34 @BindView(R.id.btn_send) 35 Button btnSend; 36 @BindView(R.id.btn_out) 37 Button btnOut; 38 39 @Override 40 protected void onCreate(Bundle savedInstanceState) { 41 super.onCreate(savedInstanceState); 42 setContentView(R.layout.activity_main2); 43 ButterKnife.bind(this); 44 //注册消息观察者 45 registerObserver(); 46 } 47 48 private void registerObserver() { 49 observer = new Observer<List<IMMessage>>() { 50 51 @Override 52 53 54 public void onEvent(List<IMMessage> imMessages) { 55 IMMessage message = imMessages.get(0); 56 String content = message.getContent(); 57 String nick = message.getFromNick(); 58 tvRecivetvIn.setText(nick+"--->"+content); 59 account=message.getFromAccount(); 60 } 61 }; 62 NIMClient.getService(MsgServiceObserve.class) 63 .observeReceiveMessage(observer,true); 64 } 65 66 @OnClick({R.id.btn_select_people, R.id.btn_send, R.id.btn_out}) 67 public void onViewClicked(View view) { 68 switch (view.getId()) { 69 case R.id.btn_select_people://选择联系人 70 71 break; 72 case R.id.btn_send://发送按钮 73 sendMessage(); 74 break; 75 case R.id.btn_out://退出登录 76 loginOut(); 77 break; 78 } 79 } 80 81 private void loginOut() { 82 NIMClient.getService(AuthService.class).logout(); 83 finish(); 84 startActivity(new Intent(Main2Activity.this,MainActivity.class)); 85 } 86 87 private void sendMessage() { 88 String text=etInput.getText().toString(); 89 IMMessage imMessage= MessageBuilder.createTextMessage(account, SessionTypeEnum.P2P,text); 90 NIMClient.getService(MsgService.class).sendMessage(imMessage,false); 91 tvSendOut.setText(text); 92 etInput.setText(""); 93 } 94 95 @Override 96 protected void onDestroy() { 97 super.onDestroy(); 98 NIMClient.getService(MsgServiceObserve.class) 99 .observeReceiveMessage(observer,false); 100 } 101 }