基于WIFI-Direct的聊天应用程序 - Android

时间:2018-06-11 17:47:37

标签: sockets chat wifi-direct

我有一个与wifi-direct一起使用的聊天应用程序。两个移动设备正确连接Wifi-Direct。
客户端设备正确地向服务器设备发送文本消息。 问题是服务器设备尝试向客户端设备发送文本

仅当两个设备同时按下发送按钮时,服务器的消息才会显示在客户端设备中。这是因为只有当按下发送按钮时,才会启动服务器或客户端类的实例,并调用套接字的read功能。
有谁能告诉我哪里错了?
我应该如何异步接收消息,我的意思是每当其他设备按下发送按钮时。

这是MainActivity

public class MainActivity extends AppCompatActivity  {

Button startButton;
TextView devicesList;
ListView listView;
static TextView msg;
Intent chatPage;

boolean serverOrClient;

private final IntentFilter intentFilter = new IntentFilter();
WifiP2pManager mManager;
WifiP2pManager.Channel mChannel;
BroadcastReceiver mReceiver;

IntentFilter mIntentFilter;
public static ArrayList<WifiP2pDevice> peers = new ArrayList<>();
private WifiP2pDeviceAdapter adapter;

private ArrayAdapter myAdapter;
ArrayList<String> deviceNames;


public void showMsg (String message){
    Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    startButton = (Button) findViewById(R.id.startButton);
    listView = (ListView) findViewById(R.id.listitem);
    //msg = (TextView) findViewById(R.id.msg);

    initFilter();

    //adapter = new WifiP2pDeviceAdapter(this,peers);
    //listView.setAdapter(adapter);
    deviceNames = new ArrayList<>();
    for(int i = 0 ; i < peers.size() ; i++){
        deviceNames.add(peers.get(i).deviceName.toString());
    }

    myAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, deviceNames );
    listView.setAdapter(myAdapter);

    mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
    mChannel = mManager.initialize(this, getMainLooper(), null);
    mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            int position = i; //Integer.parseInt(v.getTag().toString());
            WifiP2pDevice device = peers.get(position);
            switch (device.status){
                case WifiP2pDevice.AVAILABLE:
                case WifiP2pDevice.CONNECTED:
                case WifiP2pDevice.INVITED:
                    connect(device);
                    break;
                case WifiP2pDevice.FAILED:
                case WifiP2pDevice.UNAVAILABLE:
                    Toast.makeText(getApplicationContext(), String.format(Locale.getDefault(),"status=%d",device.status),Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    });

}

private void initFilter() {
    //  Indicates a change in the Wi-Fi P2P status.
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);

    // Indicates a change in the list of available peers.
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);

    // Indicates the state of Wi-Fi P2P connectivity has changed.
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);

    // Indicates this device's details have changed.
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
}

/* register the broadcast receiver with the intent values to be matched */
@Override
protected void onResume() {
    super.onResume();
    registerReceiver(mReceiver, intentFilter);
    discoverPeers();
}

/* unregister the broadcast receiver */
@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(mReceiver);
    stopPeerDiscovery();
}

private void discoverPeers(){
    mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
        @Override
        public void onSuccess() {
            Log.e("discover","onSuccess");
        }

        @Override
        public void onFailure(int reason) {

        }
    });
}
private void stopPeerDiscovery(){

    mManager.stopPeerDiscovery(mChannel, new WifiP2pManager.ActionListener() {
        @Override
        public void onSuccess() {
            showMsg("stopPeerDiscovery: onSuccess");
            Log.e("stopPeerDiscovery","onSuccess");
        }

        @Override
        public void onFailure(int reason) {
            switch (reason){
                case WifiP2pManager.ERROR:
                    Log.e("stopPeerDiscovery","ERROR");
                    break;
                case WifiP2pManager.P2P_UNSUPPORTED:
                    Log.e("stopPeerDiscovery","P2P_UNSUPPORTED");
                    break;
                case WifiP2pManager.BUSY:
                    Log.e("stopPeerDiscovery","BUSY");
                    break;
                case WifiP2pManager.NO_SERVICE_REQUESTS:
                    Log.e("stopPeerDiscovery","NO_SERVICE_REQUESTS");
                    break;
            }
        }
    });
}

public void connect(final WifiP2pDevice device) {
    // Picking the selected device found on the network.

    WifiP2pConfig config = new WifiP2pConfig();
    config.deviceAddress = device.deviceAddress;
    config.wps.setup = WpsInfo.PBC;

    Log.i("deviceAddress connect", String.valueOf(device.deviceAddress));

    mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {

        @Override
        public void onSuccess() {

            Log.e("connect","onSuccess");
            showMsg("connected.");
        }

        @Override
        public void onFailure(int reason) {
            switch (reason){
                case WifiP2pManager.ERROR:
                    Log.e("connect","ERROR");
                    break;
                case WifiP2pManager.P2P_UNSUPPORTED:
                    Log.e("connect","P2P_UNSUPPORTED");
                    break;
                case WifiP2pManager.BUSY:
                    Log.e("connect","BUSY");
                    break;
                case WifiP2pManager.NO_SERVICE_REQUESTS:
                    Log.e("connect","NO_SERVICE_REQUESTS");
                    break;
            }
        }
    });
}

public void openChat(WifiP2pInfo wifiP2pInfo, boolean serverOrClient){  //false for client and vice versa
    Log.i("wifiP2pinfo MActivity", String.valueOf(wifiP2pInfo));
    //serverOrClient = false;
    chatPage = new Intent(getApplicationContext(), Chat.class).putExtra("serverOrClient",serverOrClient);
    chatPage.putExtra("WifiP2pInfo",wifiP2pInfo);
    startActivity(chatPage);
}

public void search(View v) {
    onResume();
    Log.e("peers",peers.toString());
    for(int i = 0 ; i < peers.size() ; i++){
        deviceNames.add(peers.get(i).deviceName.toString());
    }
    myAdapter.notifyDataSetChanged();
}

}


服务器类:

public class Server extends Thread {
InetAddress address;
public static  int PORT = 1234;
String msgToSend;

public Server(InetAddress groupOwnerAddress){
    address = groupOwnerAddress;
}

@Override
public void run() {
    try {
        ServerSocket serverSocket = new ServerSocket(PORT,5,address);
        Socket socket = null;
        while (true){
            socket = serverSocket.accept();
            System.out.println("Add connection:"+socket.getInetAddress()+":"+socket.getPort());
            new HandlerThread(socket);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private class HandlerThread implements Runnable {
    private Socket socket;
    public HandlerThread(Socket client) {
        socket = client;
        new Thread(this).start();
    }
    public void run() {
        Log.i("in ane doros shod",Chat.msgToSend );

        try {
            // Read client data
            DataInputStream input = new DataInputStream(socket.getInputStream());
            //This should pay attention to the write method of the client output stream,
            // otherwise it will throw EOFException
            String clientInputStr = input.readUTF();
            // Processing client data
            System.out.println("Client sent over the content:" + clientInputStr);

            Chat.updateMessagesfromClient(clientInputStr);
            // Reply to the client
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());

            msgToSend = Chat.getMsgToSend();
            if( msgToSend != null) {
                out.writeUTF(msgToSend);
                Chat.updateMessagesfromServer(msgToSend);
            }
            msgToSend = "";
            input.close();
        } catch (Exception e) {
            System.out.println("server run abnormal: " + e.getMessage());
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (Exception e) {
                    socket = null;
                    System.out.println("server finally abnormal:" + e.getMessage());
                }
            }
        }
    }
}
}


客户类:

public class Client extends Thread {
InetAddress address;
String msgToSend;

public Client(InetAddress address){
    this.address = address;
}
@Override
public void run() {
    communication();
}


private void communication(){
    Socket socket = null;
    try {
        //Create a stream socket and connect it to the
        //specified port number on the specified host
        socket = new Socket(address, Server.PORT);


        //Read server data
        DataInputStream input = new DataInputStream(socket.getInputStream());

        //Send data to the server
        DataOutputStream out = new DataOutputStream(socket.getOutputStream());

        msgToSend = Chat.getMsgToSend();
        if(msgToSend != null ) {
            out.writeUTF(msgToSend);
            Chat.updateMessagesfromClient(msgToSend);
        }
        msgToSend = null;

        String ret = input.readUTF();
        Log.i("server returns: " , ret);
        Log.i("in ane doros shod",Chat.msgToSend );
        Chat.updateMessagesfromServer(ret);

        input.close();
    } catch (Exception e) {
        System.out.println("Client exception:" + e.getMessage());
    } finally {
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                socket = null;
                System.out.println("Clients finally abnormal:" + e.getMessage());
            }
        }
    }
}
}

和启动客户端或服务器的聊天类obj:

public class Chat extends AppCompatActivity {

TextView otherDevicename;
Button sendBbutton;
EditText textTosend;

static String  msgToSend;
Server server;
Client client;
InetAddress mygroupOwnerAddress;
boolean serverOrClient;
WifiP2pInfo wifiP2pInfo;

public static ArrayList<String> msg_content = new ArrayList<>();
public static ListView messages;
public static ArrayAdapter msg_adapter;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.chat_page);
    serverOrClient = getIntent().getBooleanExtra("serverOrClient",true);

    wifiP2pInfo = getIntent().getExtras().getParcelable("WifiP2pInfo");
    Log.i("WPI chat" , wifiP2pInfo.toString() );


    if(wifiP2pInfo != null) {
        setSender(wifiP2pInfo, serverOrClient);
    }

    sendBbutton = (Button) findViewById(R.id.sendButton);
    textTosend = (EditText) findViewById(R.id.textToSend);
    messages = (ListView) findViewById(R.id.messages);

    msg_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, msg_content );
    msg_content.add("The chat goes Below...");
    messages.setAdapter(msg_adapter);

    otherDevicename = (TextView) findViewById(R.id.otherDeviceName);
    otherDevicename.setText("this is a new chat");
    msgToSend = "thisShitIsNull";
}

public void showMsg(String message){ Toast.makeText(this, message, Toast.LENGTH_LONG).show(); }

public static String getMsgToSend() {
    return msgToSend;
}

public void fuckingSend(View view){
   EditText textTosend2 = (EditText) findViewById(R.id.textToSend);
    if(String.valueOf(textTosend2.getText()) != null){
        msgToSend = String.valueOf(textTosend2.getText());
        showMsg(msgToSend+" from Fucking Send.");

        if(serverOrClient == true){ // for server
            updateMessagesfromServer("");
            server = new Server(  wifiP2pInfo.groupOwnerAddress );
            server.start();
        }else{    // for client
            updateMessagesfromClient("");
            client = new Client(  wifiP2pInfo.groupOwnerAddress );
            client.start();
        }


    }

    Log.i("msg to send:",msgToSend);
   }

private void setSender(WifiP2pInfo wifiP2pInfo, boolean serverOrClient) {
    mygroupOwnerAddress = wifiP2pInfo.groupOwnerAddress;

    if (wifiP2pInfo.groupFormed && wifiP2pInfo.isGroupOwner && serverOrClient == true) {
        // Do whatever tasks are specific to the group owner.
        // One common case is creating a server thread and accepting
        // incoming connections.
        server = new Server(mygroupOwnerAddress);
        server.start();
        showMsg("server created.");
    } else if (wifiP2pInfo.groupFormed && serverOrClient == false) {
        // The other device acts as the client. In this case,
        // you'll want to create a client thread that connects to the group
        // owner.
        client = new Client(mygroupOwnerAddress);
        client.start();
        showMsg("client created");
    }
}

static void updateMessagesfromServer(String msgs){
    if(msgs != null){
        msg_adapter.notifyDataSetChanged();

    }
}

public static void updateMessagesfromClient(String ret) {
    if(ret != null){
        msg_adapter.notifyDataSetChanged();
    }
}
}


这是github上的项目链接:link

0 个答案:

没有答案