ChatAPP --- 好友聊天

程凯定
2023-12-01

一,简介在局域网内,使用IP的点对点通信,使用socket进行TCP/IP协议通信,并使用此协议进行文件传输,因为大家都在局域网内,不容易丢失通信包,所以不使用UDP协议。


二,原理
发送端:向另一台手机发送信息----并显示在屏幕上
接收端:接收另一台手机发过来的信息----并显示在屏幕上

三,布局
主布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/mainlayout"
    tools:context=".activitys.ChatActivity">

    <RelativeLayout
        android:id="@+id/relate"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_margin="14dp"
        android:layout_alignParentBottom="true"
        >
        <Button
            android:id="@+id/sendfile"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:text="@string/sendfile"
            />
        <Button
            android:id="@+id/send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@id/sendfile"
            android:text="@string/send"
            />
        <EditText
            android:id="@+id/et"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_toLeftOf="@+id/send"
            android:layout_marginRight="5dp"
            />

    </RelativeLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/relate"
        android:layout_marginTop="25dp"
        android:layout_marginLeft="14dp"
        android:layout_marginRight="14dp"
        />


</RelativeLayout>

ChatAdapter适配器布局
chat_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activitys.ChatActivity">

    <RelativeLayout
        android:id="@+id/relate_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        >
        <ImageView
            android:id="@+id/icon1"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@mipmap/head"
            android:layout_centerVertical="true"
            />
        <ImageView
            android:id="@+id/file_icon1"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/ic_launcher"
            android:layout_toRightOf="@+id/icon1"
            android:layout_marginLeft="10dp"
            />
        <TextView
            android:id="@+id/tv1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:text="对方"
            android:textSize="15sp"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/icon1"
            android:visibility="gone"
            />
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/relate_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/relate_1"
        android:visibility="gone"
        >
        <ImageView
            android:id="@+id/icon2"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@mipmap/head"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            />
        <ImageView
            android:id="@+id/file_icon2"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@mipmap/ic_launcher"
            android:layout_toLeftOf="@+id/icon2"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            />

        <TextView
            android:id="@+id/tv2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="自己"
            android:textSize="15sp"
            android:layout_toLeftOf="@+id/icon2"
            android:layout_centerVertical="true"
            android:layout_marginRight="10dp"
            android:visibility="gone"
        />
    </RelativeLayout>

</RelativeLayout>

发送端布局

/**
     * 发送聊天语句
     */
    @OnClick(R.id.send)
    public void Send(){
        send_str = et.getText().toString().trim();
        if (!send_str.isEmpty()){
            Chat chat = new Chat();
            chat.setId(1);
            chat.setTalk(send_str);
            chat.setFiletype(getString(R.string.talk));
            chats.add(chat);
            chatAdapter.notifyDataSetChanged();
            //自动滑到最底端
            mRecycle.scrollToPosition(chatAdapter.getItemCount()-1);
            Thread thread = new Thread(){
                @Override
                public void run() {
                    super.run();

                    try {
                        sockets = new Socket(ip_diu,8000);

                        outputStream = sockets.getOutputStream();

                        byte[] buffer = TalkUtil.CreateJson(getString(R.string.talk) , send_str);
                        outputStream.write(buffer);

                    } catch (IOException e) {
                        e.printStackTrace();
                    }


                }
            };
            thread.start();
        }else {
            Toast.makeText(this,R.string.send_ok , Toast.LENGTH_SHORT).show();
        }
    }

接收端

  public class  MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String msg = intent.getStringExtra("msg");
            String type;
            try {
                JSONObject jsonObject = new JSONObject(msg);
                type = jsonObject.getString(Constant.type_key);
                if (type.equals(getString(R.string.talk))){
                    msg = jsonObject.getString(Constant.talk_key);
                    Chat chat = new Chat();
                    chat.setId(-1);
                    chat.setTalk(msg);
                    chat.setFiletype(type);
                    chats.add(chat);
                    chatAdapter.notifyDataSetChanged();
                }else if (type.equals(getString(R.string.file))){
                    msg = jsonObject.getString(Constant.talk_key);
                    Chat chat = new Chat();
                    chat.setId(-1);
                    chat.setTalk(msg);
                    chat.setFiletype(type);
                    chats.add(chat);
                    chatAdapter.notifyDataSetChanged();
                }
                mRecycle.scrollToPosition(chatAdapter.getItemCount()-1);

            }catch (JSONException e){
                e.printStackTrace();
            }


        }
    }

适配器

package com.peng.linchat.adapter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.peng.linchat.R;
import com.peng.linchat.bean.Chat;
import com.peng.linchat.util.StringUtil;

import java.util.List;


public class ChatAdapter  extends RecyclerView.Adapter<ChatAdapter.ViewHolder> {
    private Context mContext;
    private List<Chat> chats;

    /**
     * 构造函数,传入数据
     * @param mContext
     * @param friends
     */
    public ChatAdapter(Context mContext, List<Chat> friends) {
        this.mContext = mContext;
        this.chats = friends;
    }


    /**
     * 设置holder
     */
    static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView ch_1 , ch_2 ;
        public ImageView icon_1 , icon_2 , file_icon_1 , file_icon_2;
        public RelativeLayout relativeLayout_1 , relativeLayout_2;

        public ViewHolder(View itemView) {
            super(itemView);
            ch_1 = (TextView) itemView.findViewById(R.id.tv1);
            ch_2 = (TextView) itemView.findViewById(R.id.tv2);
            icon_1 = (ImageView) itemView.findViewById(R.id.icon1);
            icon_2 = (ImageView) itemView.findViewById(R.id.icon2);
            file_icon_1 = (ImageView) itemView.findViewById(R.id.file_icon1);
            file_icon_2 = (ImageView) itemView.findViewById(R.id.file_icon2);
            relativeLayout_1 = (RelativeLayout) itemView.findViewById(R.id.relate_1);
            relativeLayout_2 = (RelativeLayout) itemView.findViewById(R.id.relate_2);
        }
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_item , null);
        ViewHolder viewHolder = new ViewHolder(view);

        return viewHolder;
    }

    /**
     * 更新对话框时的显示
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Chat chat = chats.get(position);
        if (chat.getId() == -1){
            holder.relativeLayout_1.setVisibility(View.VISIBLE);
            holder.relativeLayout_2.setVisibility(View.GONE);
            if (chat.getFiletype().equals(mContext.getString(R.string.talk))){
                holder.ch_1.setVisibility(View.VISIBLE);
                holder.ch_1.setText(chat.getTalk());
                holder.file_icon_1.setVisibility(View.GONE);
            }else{
                holder.ch_1.setVisibility(View.GONE);
                holder.file_icon_1.setVisibility(View.VISIBLE);
                String filename = chat.getTalk();
                holder.file_icon_1.setImageResource(StringUtil.geticonid(filename));
            }
            holder.icon_1.setImageDrawable(mContext.getResources().getDrawable((R.mipmap.head)));
        }else{
            holder.relativeLayout_1.setVisibility(View.GONE);
            holder.relativeLayout_2.setVisibility(View.VISIBLE);
            if (chat.getFiletype().equals(mContext.getString(R.string.talk))){
                holder.ch_2.setVisibility(View.VISIBLE);
                holder.ch_2.setText(chat.getTalk());
                holder.file_icon_2.setVisibility(View.GONE);
            }else{
                holder.ch_2.setVisibility(View.GONE);
                holder.file_icon_2.setVisibility(View.VISIBLE);
                String filename = chat.getTalk();
                holder.file_icon_2.setImageResource(StringUtil.geticonid(filename));
            }
            holder.icon_2.setImageDrawable(mContext.getResources().getDrawable((R.mipmap.head)));
        }
    }

    @Override
    public int getItemCount() {
        return chats.size();
    }

}

 

 类似资料: