classic bluetooth chat 五

来源:互联网 发布:tengine windows安装 编辑:程序博客网 时间:2024/06/07 17:14

第5节 界面使用ConnectionManager

ConnectionManager已经设计完成了,它的价值需要在ChatActivity中体现出来。

5.1 监听ConnectionManager

实现对ConnectionManager各个状态的监听,当ConnectionManager的状态有变化、收到发送的数据时,需要让ChatActivity知道,它才能将各种变化反应到用户界面上。

5.1.1 创建监听器

ConnectionManager定义了ConnectionListener接口,状态变化、数据的接收可以通过这个接口获得。创建一个ConnectionListener监听器,

public class ChatActivity extends AppCompatActivity {    ......    private ConnectionManager.ConnectionListener mConnectionListener = new ConnectionManager.ConnectionListener() {       @Override       public void onConnectStateChange(int oldState, int State) {       }       @Override       public void onListenStateChange(int oldState, int State) {       }       @Override       public void onSendData(boolean suc, byte[] data) {       }       @Override       public void onReadData(byte[] data) {       }    };    ......}
  • 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
  • 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

5.1.2 创建Handler

因为监听器触发的函数不一定是在UI线程被调用的,例如onConnectStateChange(),所以不能在监听器当中对界面做修改,必须把界面更新的任务交给UI线程进行。

安卓系统提供了Handler的机制,让其它非UI线程能通过Handler把界面更新的操作,从工作线程布置给主线程完成。

  1. 创建一个能在主线程当中工作的Handler,

    public class ChatActivity extends AppCompatActivity {    ......    private final static int MSG_SENT_DATA = 0;    private final static int MSG_RECEIVE_DATA = 1;    private final static int MSG_UPDATE_UI = 2;    //不使用参数创建Handler,说明这个Handler是给主线程服务的    private Handler mHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case MSG_SENT_DATA: {                    //UI线程处理发送成功的数据,                    //把文字内容展示到主界面上                }                break;                case MSG_RECEIVE_DATA: {                    //UI线程处理接收到的对方发送的数据,                    //把文字内容展示到主界面上                }                break;                case MSG_UPDATE_UI: {                    //更新界面上的菜单等显示状态                    }                break;            }        }    };    ......}
    • 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
    • 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
  2. ConnectionManager通知的内容,转交给主线程的Handler处理,

    private ConnectionManager.ConnectionListener mConnectionListener = new ConnectionManager.ConnectionListener() {    @Override    public void onConnectStateChange(int oldState, int State) {        //连接状态的变化通知给UI线程,请UI线程处理        mHandler.obtainMessage(MSG_UPDATE_UI).sendToTarget();    }    @Override    public void onListenStateChange(int oldState, int State) {        //监听状态的变化通知给UI线程,请UI线程处理        mHandler.obtainMessage(MSG_UPDATE_UI).sendToTarget();    }    @Override    public void onSendData(boolean suc, byte[] data) {        //将发送的数据交给UI线程,请UI线程处理        mHandler.obtainMessage(MSG_SENT_DATA, suc?1:0, 0, data).sendToTarget();    }    @Override    public void onReadData(byte[] data) {        //将收到的数据交给UI线程,请UI线程处理        mHandler.obtainMessage(MSG_RECEIVE_DATA,  data).sendToTarget();    }};
    • 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
    • 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
  3. 创建ConnectionManager,添加监听,

    private ConnectionManager mConnectionManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_chat);    ......    mConnectionManager = new ConnectionManager(mConnectionListener);        ......}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

5.2 启动与停止监听

当聊天应用运行起来的时候,需要开启对其它蓝牙设备可能接入的监听,

private ConnectionManager mConnectionManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_chat);    ......    //开启监听    mConnectionManager.startListen();    ......}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

当应用退出的时候,要断开可能存在的连接并停止监听,

@Overrideprotected void onDestroy() {    super.onDestroy();    //移除Handler中可能存在的各种任务    mHandler.removeMessages(MSG_UPDATE_UI);    mHandler.removeMessages(MSG_SENT_DATA);    mHandler.removeMessages(MSG_RECEIVE_DATA);    //停止监听    if(mConnectionManager != null) {        mConnectionManager.disconnect();        mConnectionManager.stopListen();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

5.3 启动连接

5.3.1 通过选择设备主动连接

当用户点击菜单栏的启动连接菜单项时,会启动DeviceListActivity,让用户从刷新的列表中,选取一个希望连接的设备。用户选择后,会把选中设备的地址返回给ChatActivity

这样,就可以利用ConnectionManager发起主动连接的请求了,

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {  super.onActivityResult(requestCode, resultCode, data);  if(requestCode == RESULT_CODE_BTDEVICE && resultCode == RESULT_OK) {      //取出传回来的地址      String deviceAddr = data.getStringExtra("DEVICE_ADDR");      //得到蓝牙设备的地址后,就可以通过ConnectionManager模块去连接设备      mConnectionManager.connect(deviceAddr);  }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

之后,ConnectionManager的各种状态变化,就会通过监听器ConnectionListener,传递到ChatActivity当中,据此更新界面就好了。

5.3.2 通过监听被动连接

这种情况,并不需要用户去做任何点击的操作。 
之后,ConnectionManager的各种状态变化,就会通过监听器ConnectionListener,传递到ChatActivity当中,据此更新界面就好了。

5.3.3 菜单项的改变

我们之前已经通过ChatActivityonCreateOptionsMenu()方法,把菜单项添加到了菜单栏。现在需要菜单项随着ConnectionManager状态的变化,跟着做变化了。

  1. 当监听器的onConnectStateChange()或者onListenStateChange被触发后,我们将变化通过Handler通知到了UI线程,

    private ConnectionManager.ConnectionListener mConnectionListener = new ConnectionManager.ConnectionListener() {    @Override    public void onConnectStateChange(int oldState, int State) {        //连接状态的变化通知给UI线程,请UI线程处理        mHandler.obtainMessage(MSG_UPDATE_UI).sendToTarget();    }    @Override    public void onListenStateChange(int oldState, int State) {        //监听状态的变化通知给UI线程,请UI线程处理        mHandler.obtainMessage(MSG_UPDATE_UI).sendToTarget();    }    ......};---------------------------------------------private Handler mHandler = new Handler() {  @Override  public void handleMessage(Message msg) {      switch (msg.what) {          ......          case MSG_UPDATE_UI: {              //更新界面上的菜单等显示状态                updateUI();            }          break;      }  }};
    • 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
    • 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

    在更新UI到方法updateUI()中,修改菜单项的显示,

    private void updateUI(){    if(mConnectionManager == null) {        return;    }    //默认情况下,禁止点击发送按钮和文字编辑框    if(mConnectionMenuItem == null) {        mMessageEditor.setEnabled(false);        mSendBtn.setEnabled(false);        return;    }    //设置成连接状态,允许点击发送按钮和文字编辑框    if(mConnectionManager.getCurrentConnectState() == ConnectionManager.CONNECT_STATE_CONNECTED) {        mConnectionMenuItem.setTitle(R.string.disconnect);        mMessageEditor.setEnabled(true);        mSendBtn.setEnabled(true);    }    //设置成正在连接状态,禁止点击发送按钮和文字编辑框    else if(mConnectionManager.getCurrentConnectState() == ConnectionManager.CONNECT_STATE_CONNECTING) {        mConnectionMenuItem.setTitle(R.string.cancel);        mMessageEditor.setEnabled(false);        mSendBtn.setEnabled(false);    }    //设置成未连接状态,禁止点击发送按钮和文字编辑框    else if(mConnectionManager.getCurrentConnectState() == ConnectionManager.CONNECT_STATE_IDLE) {        mConnectionMenuItem.setTitle(R.string.connect);        mMessageEditor.setEnabled(false);        mSendBtn.setEnabled(false);    }}
    • 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
    • 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
  2. 菜单项的响应也需要根据当前的连接状态,做进一步的修改,

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {    switch (item.getItemId())    {        case R.id.connect_menu: {            //如果当前处于连接状态,点击后就取消当前连接            if(mConnectionManager.getCurrentConnectState() == ConnectionManager.CONNECT_STATE_CONNECTED) {                mConnectionManager.disconnect();            }            //如果当前处于正在连接,点击后就取消当前连接            else if(mConnectionManager.getCurrentConnectState() == ConnectionManager.CONNECT_STATE_CONNECTING) {                mConnectionManager.disconnect();            }            //如果当前处于未连接状态,点击后就启动查找当前可连接设备的Activity            else if(mConnectionManager.getCurrentConnectState() == ConnectionManager.CONNECT_STATE_IDLE) {                Intent i = new Intent(ChatActivity.this, DeviceListActivity.class);                startActivityForResult(i, RESULT_CODE_BTDEVICE);            }        }        return true;        ......    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

5.4 发送与显示数据

聊天文字发送成功或者接收到对方发来的文字时,要显示到列表中。为此,我们需要专门设计一个Adapter来展示它们。

5.4.1 文字信息的数据结构

首先定义一个记录每条信息的数据结构ChatMessage,每一条消息要注明是由谁发来的,是自己还是对方,

public class ChatMessage {   //主动发出的消息   static public final int MSG_SENDER_ME = 0;   //接收到的消息   static public final int MSG_SENDER_OTHERS = 1;   public int messageSender;   public String messageContent;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5.4.2 信息展示的Adapter

我们采用类似微信聊天的样子来展示聊天内容。每条消息的背景图片是9patch形式的PNG图片,将它们放在res\drawable目录中。针对不同的屏幕像素密度,设计了对应的图片,放到对应的drawable目录下就行了。例如为xxhdip设计的背景图片就放在res\drawable-xxhdip目录中。

这些图片可以在示例代码中获得。

  1. 定义展示对方发来信息的布局-others_list_item.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal" android:layout_width="match_parent"    android:layout_height="wrap_content"    android:minHeight="58dp"    android:padding="5dp">    <!--显示类似头像的图片-->    <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@mipmap/ic_device_bluetooth"/>    <FrameLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_weight="1"> ---设置为1,让文字显示尽情利用右边区域        <!--显示文字内容-->        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="1"            android:id="@+id/message_content"            android:padding="5dp"            android:textSize="16sp"            android:gravity="center_vertical"            android:background="@drawable/others"/>    </FrameLayout></LinearLayout>
    • 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
    • 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
  2. 定义展示自己发送信息的布局-me_list_item.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal" android:layout_width="match_parent"    android:layout_height="wrap_content"    android:minHeight="58dp"    android:padding="5dp"    android:gravity="right">    <FrameLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_weight="1"> ---设置为1,让文字显示尽情利用左边区域        <!--显示文字内容-->        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/message_content"            android:gravity="center_vertical"            android:layout_gravity="right"            android:padding="5dp"            android:textSize="16sp"            android:background="@drawable/me"/>    </FrameLayout>    <!--显示类似头像的图片-->    <ImageView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@mipmap/ic_device_bluetooth"/></LinearLayout>
    • 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
    • 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
  3. 定义Adapter-MessageAdapter,

    public class MessageAdapter extends ArrayAdapter<ChatMessage> {    private final LayoutInflater mInflater;    private int mResourceMe;    private int mResourceOthers;    //要指定自己发送的消息显示用的布局-me_list_item,    //以及对方发送消息显示用的布局-others_list_item    public MessageAdapter(Context context, int resourceMe, int resourceOthers) {        super(context, 0);        mInflater = LayoutInflater.from(context);        mResourceMe = resourceMe;        mResourceOthers = resourceOthers;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ChatMessage message = getItem(position);        //根据消息类型的不同,使用不同的布局作为消息项        convertView = mInflater.inflate(message.messageSender == ChatMessage.MSG_SENDER_ME ? mResourceMe : mResourceOthers, parent, false);        //显示消息的内容        TextView name = (TextView) convertView.findViewById(R.id.message_content);        name.setText(message.messageContent);        return convertView;    }}
    • 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
    • 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
  4. 使用聊天列表,

    @Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_chat);    ......    mMessageListView = (ListView) findViewById(R.id.message_list);    MessageAdapter adapter = new MessageAdapter(this, R.layout.me_list_item, R.layout.others_list_item);    mMessageListView.setAdapter(adapter);    ......}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

5.4.3 文字的发送

当连接建立以后,禁止点击的发送按钮和文字编辑框将被解禁。再文字编辑框中编辑好文字,点击发送按钮,就能将文字发送出去了。

  1. 为按钮创建监听器,当点击后,获取文字编辑框中的数据,再使用ConnectionManager提供的接口,把数据发送出去,

    private View.OnClickListener mSendClickListener = new View.OnClickListener() {    @Override    public void onClick(View v) {        //获取要发送的文字内容        String content = mMessageEditor.getText().toString();        if(content != null) {            content = content.trim();            if(content.length() > 0) {                //利用ConnectionManager发送数据                boolean ret = mConnectionManager.sendData(content.getBytes());                if(!ret) {                    Toast.makeText(ChatActivity.this, R.string.send_fail, Toast.LENGTH_SHORT).show();                }            }        }    }};
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  2. 注册监听函数,

    @Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_chat);    ......    mSendBtn = (ImageButton) findViewById(R.id.send_btn);    mSendBtn.setOnClickListener(mSendClickListener);    ......}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  3. ConnectionListeneronSendData回调方法中,将发送结果传递给UI线程,让UI线程把聊天内容更新到消息列表中,

    private ConnectionManager.ConnectionListener mConnectionListener = new ConnectionManager.ConnectionListener() {    ......    @Override    public void onSendData(boolean suc, byte[] data) {        //发送的结果传递给UI线程,文字的二进制内容包含在data参数中        mHandler.obtainMessage(MSG_SENT_DATA, suc?1:0, 0, data).sendToTarget();    }    ......};---------------------------------------------private Handler mHandler = new Handler() {    @Override    public void handleMessage(Message msg) {        switch (msg.what) {            case MSG_SENT_DATA: {                //获取发送的文字内容                byte [] data = (byte []) msg.obj;                boolean suc = msg.arg1 == 1;                if(data != null && suc) {                    //发送成功后创建消息                    ChatMessage chatMsg = new ChatMessage();                    chatMsg.messageSender = ChatMessage.MSG_SENDER_ME;                    chatMsg.messageContent = new String(data);                    //将消息展示到消息列表中                    MessageAdapter adapter = (MessageAdapter) mMessageListView.getAdapter();                    adapter.add(chatMsg);                    adapter.notifyDataSetChanged();                    mMessageEditor.setText("");                }            }            break;            ......        }    }};
    • 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
    • 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

5.4.4 文字的接收

当接收到对方发来的消息时,ConnectionListeneronReadData回调方法,将发送结果传递给UI线程,让UI线程把聊天内容更新到消息列表中,

private ConnectionManager.ConnectionListener mConnectionListener = new ConnectionManager.ConnectionListener() {    ......    @Override    public void onReadData(byte[] data) {        //接收到的内容传递给UI线程,文字的二进制内容包含在data参数中        mHandler.obtainMessage(MSG_RECEIVE_DATA,  data).sendToTarget();    }};-------------------------------------------------private Handler mHandler = new Handler() {    @Override    public void handleMessage(Message msg) {        switch (msg.what) {            ......            case MSG_RECEIVE_DATA: {                byte [] data = (byte []) msg.obj;                if(data != null) {                    ChatMessage chatMsg = new ChatMessage();                    chatMsg.messageSender = ChatMessage.MSG_SENDER_OTHERS;                    chatMsg.messageContent = new String(data);                    //将消息展示到消息列表中                    MessageAdapter adapter = (MessageAdapter) mMessageListView.getAdapter();                    adapter.add(chatMsg);                    adapter.notifyDataSetChanged();                }            }            break;            ......        }    }};
0 0