При отправке сообщения происходит сбой приложения обмена сообщениями Wi-Fi. - PullRequest
0 голосов
/ 09 января 2020

Это приложение для отправки текстового сообщения через Wi-Fi прямой Api. я использовал встроенный API для этого. код работает, обнаружение устройств также, но проблема при отправке сообщения, когда нажмите кнопку отправки

Я пробовал это решение также: App cra sh при отправке данных через сокет с использованием соединения WifiP2p но все равно приложение cra sh всякий раз, когда нажимается кнопка отправки.

MainActivity:

    public class MainActivity extends AppCompatActivity{
    Switch switch1;
    Button btnOnOff, btnSend, btnDiscover;
    ListView listView;
    TextView read_msg_box, connectionStatus;
    EditText writeMsg;
    WifiManager wifiManager;
    WifiP2pManager.Channel mChannel;
    WifiP2pManager mManager;
    BroadcastReceiver mReceiver;
    IntentFilter mIntentFilter;
    List <WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
    String[] deviceNameArray;
    WifiP2pDevice[] deviceArray;
    static final int MESSAGE_READ = 1;
    ServerClass serverClass;
    ClientClass clientClass;
    SendReceive sendReceive;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initialWork();
        exqListner();
    }

    Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch(msg.what){
                case MESSAGE_READ:
                    byte[] readbuff = (byte[]) msg.obj;
                    String tempMsg = new String(readbuff, 0, msg.arg1);
                    read_msg_box.setText(tempMsg);
                    break;
            }
            return true;
        }
    });
    private void exqListner() {
        btnOnOff.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(wifiManager.isWifiEnabled()){
                    wifiManager.setWifiEnabled(false);
                    btnOnOff.setText("ON");
                }else{
                    wifiManager.setWifiEnabled(true);
                    btnOnOff.setText("OFF");
                }
            }
        });

        btnDiscover.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
                    @Override
                    public void onSuccess() {
                        connectionStatus.setText("Discovering started");
                    }

                    @Override
                    public void onFailure(int reason) {
                        connectionStatus.setText("Discovering starting failed");
                    }
                });
            }
        });

        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String msg = writeMsg.getText().toString();
                byte[] bytes =msg.getBytes();
                btnSend.setVisibility(View.INVISIBLE);
                if(connectionStatus.equals("Host")) {
                    serverClass.writeData(bytes);
                } else {
                    clientClass.writeData(bytes);
                }

            }
        });

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int i, long l) {
                final WifiP2pDevice device = deviceArray[i];
                WifiP2pConfig config = new WifiP2pConfig();
                config.deviceAddress = device.deviceAddress;
                mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {
                    @Override
                    public void onSuccess() {
                        Toast.makeText(getApplicationContext(), "Connected to "+device.deviceName, Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onFailure(int reason) {
                        Toast.makeText(getApplicationContext(), "Not Connected", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }

    private void initialWork() {
        btnDiscover = (Button) findViewById(R.id.discover);
        btnOnOff = (Button) findViewById(R.id.onOff);
        btnSend = (Button) findViewById(R.id.sendButton);
        listView = (ListView) findViewById(R.id.peerListView);
        read_msg_box = (TextView) findViewById(R.id.readmsg);
        connectionStatus = (TextView) findViewById(R.id.connectionStatus);
        writeMsg = (EditText) findViewById(R.id.writeMsg);

        wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

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

        mReceiver = new WifiDirectBroadcastReceiver(mManager, mChannel, this);
        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
    }
    WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
        @Override
        public void onPeersAvailable(WifiP2pDeviceList peerList) {
            if(!peerList.getDeviceList().equals(peers)){
                peers.clear();
                peers.addAll(peerList.getDeviceList());
                deviceNameArray = new String[peerList.getDeviceList().size()];
                deviceArray = new WifiP2pDevice[peerList.getDeviceList().size()];
                int index = 0;
                for(WifiP2pDevice device : peerList.getDeviceList()){
                    deviceNameArray[index] = device.deviceName;
                    deviceArray[index] = device;
                    index++;
                }
                ArrayAdapter <String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, deviceNameArray);
                listView.setAdapter(adapter);
            }
            if (peers.size() == 0){
                Toast.makeText(getApplicationContext(), "No Device Found",Toast.LENGTH_SHORT).show();
                return;
            }
        }
    };

    WifiP2pManager.ConnectionInfoListener connectionInfoListener = new WifiP2pManager.ConnectionInfoListener() {
        @Override
        public void onConnectionInfoAvailable(WifiP2pInfo wifiP2pInfo) {
            final InetAddress groupOwnerAddress = wifiP2pInfo.groupOwnerAddress;
            if(wifiP2pInfo.groupFormed && wifiP2pInfo.isGroupOwner){
                connectionStatus.setText("Host");
            }
            else if (wifiP2pInfo.groupFormed){
                connectionStatus.setText("Client");
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(mReceiver, mIntentFilter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(mReceiver);
    }

    public class ServerClass extends AsyncTask<String, Integer, Boolean> {
        Socket socket;
        ServerSocket serverSocket;
        InputStream inputStream;
        OutputStream outputStream;
        @Override
        protected Boolean doInBackground(String... strings) {
            boolean result = true;
            try {
                serverSocket = new ServerSocket(8888);
                socket = serverSocket.accept();
            } catch (IOException e) {
                result = false;
                e.printStackTrace();
            }
            return result;
        }
        public void writeData(final byte[] bytes) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        outputStream.write(bytes);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            btnSend.setVisibility(View.VISIBLE);
        }

        @Override
        protected void onPostExecute(Boolean result) {
            if(result) {
                try {
                    inputStream = socket.getInputStream();
                    outputStream = socket.getOutputStream();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                new Thread(new Runnable(){
                    public void run() {
                        byte[] buffer = new byte[1024];
                        int x;
                        while (socket!=null) {
                            try {
                                x = inputStream.read(buffer);
                                if(x>0) {
                                    handler.obtainMessage(MESSAGE_READ,x,-1,buffer).sendToTarget();
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();
                btnSend.setVisibility(View.VISIBLE);
            } else {
                Toast.makeText(getApplicationContext(),"could not create sockets",Toast.LENGTH_SHORT).show();
                //restart socket assignment process
            }
        }
    }

    private class SendReceive extends  Thread{
        private Socket socket;
        private InputStream inputStream;
        private OutputStream outputStream;

        public SendReceive(Socket skt){
            socket = skt;
            try {
                inputStream = socket.getInputStream();
                outputStream = socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            byte[] buffer = new byte[1024];
            int bytes;
            while (socket != null){
                try {
                    bytes = inputStream.read(buffer);
                    if (bytes > 0){
                        handler.obtainMessage(MESSAGE_READ,bytes,-1,buffer).sendToTarget();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        public  void write(byte[] bytes){
            try {
                outputStream.write(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public class ClientClass extends AsyncTask<String, Integer, Boolean>{
        Socket socket;
        String hostAdd;
        InputStream inputStream;
        OutputStream outputStream;

        public ClientClass(InetAddress hostAddress) {
            hostAdd = hostAddress.getHostAddress();
            socket = new Socket();
        }
        @Override
        protected Boolean doInBackground(String... strings) {
            boolean result = false;
            try {
                socket.connect(new InetSocketAddress(hostAdd, 8888), 5000);
                result = true;
                return result;
            } catch (IOException e) {
                e.printStackTrace();
                result = false;
                return result;
            }
        }
        public void writeData(final byte[] bytes) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        outputStream.write(bytes);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            btnSend.setVisibility(View.VISIBLE);
        }

        @Override
        protected void onPostExecute(Boolean result) {
            if(result) {
                try {
                    inputStream = socket.getInputStream();
                    outputStream = socket.getOutputStream();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                new Thread(new Runnable(){
                    public void run() {
                        byte[] buffer = new byte[1024];
                        int x;
                        while (socket!=null) {
                            try {
                                x = inputStream.read(buffer);
                                if(x>0) {
                                    handler.obtainMessage(MESSAGE_READ,x,-1,buffer).sendToTarget();
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();
                btnSend.setVisibility(View.VISIBLE);
            } else {
                Toast.makeText(getApplicationContext(),"could not create sockets",Toast.LENGTH_SHORT).show();
            }
        }
    }
    }

Класс приемника вещания:

    public class WifiDirectBroadcastReceiver extends BroadcastReceiver {

    private WifiP2pManager mManager;
    private WifiP2pManager.Channel mChannel;
    private MainActivity mActivity;

    public WifiDirectBroadcastReceiver(WifiP2pManager mManager, WifiP2pManager.Channel mChannel, MainActivity mActivity){

        this.mActivity = mActivity;
        this.mChannel = mChannel;
        this.mManager = mManager;
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)){
            int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,-1);
            if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED){
                Toast.makeText(context,"Wifi is on",Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(context, "Wifi is off", Toast.LENGTH_SHORT).show();
            }
        }else if(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)){
            if (mManager != null){
                mManager.requestPeers(mChannel, mActivity.peerListListener);
            }
        }else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)){
            if(mManager == null){
                return;
            }
            NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
            if (networkInfo.isConnected()){
                mManager.requestConnectionInfo(mChannel, mActivity.connectionInfoListener);
            }
            else{
                mActivity.connectionStatus.setText("Device Disconnected");
            }
        }else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)){

        }
    }
    }

и xml file:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"enter code here
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <Button
        android:id="@+id/onOff"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="25dp"
        android:layout_marginTop="55dp"
        android:text="Wifi On"/>

    <Button
        android:id="@+id/discover"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/onOff"
        android:layout_alignBottom="@+id/onOff"
        android:layout_centerHorizontal="true"
        android:text="Discover" />

    <ListView
        android:id="@+id/peerListView"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/onOff"
        android:layout_marginTop="25dp"
        android:background="@android:color/holo_blue_light">
    </ListView>

    <TextView
        android:id="@+id/readmsg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentEnd="true"
        android:layout_below="@+id/peerListView"
        android:layout_marginTop="31dp"
        android:text="Message"
        android:textAlignment="center"
        android:textSize="20dp"
        android:textStyle="italic"/>

    <EditText
        android:id="@+id/writeMsg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentBottom="true"
        android:ems="10"
        android:inputType="textPersonName"
        android:layout_toStartOf="@id/sendButton"/>

    <Button
        android:id="@+id/sendButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:text="SEND"/>

    <TextView
        android:id="@+id/connectionStatus"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="15dp"
        android:textAlignment="center"
        android:text="Connection Status"
        android:textColor="@color/design_default_color_primary_dark"
        android:textSize="15dp"
        android:textStyle="italic"/>

    </RelativeLayout>

После нажатия кнопки отправки сообщение должно быть отправлено, но оно обрабатывает sh всего приложения. Это logcat трассировки стека:

  --------- beginning of crash
2020-01-10 01:40:50.640 15237-15237/com.example.wave_share E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.wave_share, PID: 15237
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1450)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:108)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:141)
        at com.example.wave_share.MainActivity$SendRecive.write(MainActivity.java:319)
        at com.example.wave_share.MainActivity$2.onClick(MainActivity.java:141)
        at android.view.View.performClick(View.java:6312)
        at android.view.View$PerformClick.run(View.java:24811)
        at android.os.Handler.handleCallback(Handler.java:794)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:176)
        at android.app.ActivityThread.main(ActivityThread.java:6651)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
2020-01-10 01:40:50.698 15237-15237/com.example.wave_share I/Process: Sending signal. PID: 15237 SIG: 9
...