0

i have been trying for some hours now to get my app (running on Android 7.1.2) to connect to a server socket on my desktop PC in my home LAN.

public class MainActivity extends AppCompatActivity {

    static final String SERVER_IP   = "192.168.XXX.XXX"; // X's are replaced by actual IP
    static final int    PORT        = 30000;

    Socket clientSocket;

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

        final Button btReceive  = (Button) findViewById(R.id.btReceive);

        final TextView txtReceivedText  = (TextView) findViewById(R.id.txtReceivedText);
        final TextView txtStatus        = (TextView) findViewById(R.id.txtStatus);



        btReceive.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {

                txtStatus.setText("Received button pressed.");

                try {

                    Socket s = new Socket(SERVER_IP, PORT);


                    BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
                    final String st = input.readLine();

                    txtReceivedText.setText(st);

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

        });

    }


}

When executed I get the output on the console in Android studio:

...
Waiting for process to come online
Connected to process 16980 on device samsung-gt_i9515-a72266ed
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.jonas.network_connector, PID: 16980
                  android.os.NetworkOnMainThreadException
                      at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
                      at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:333)
                      at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:196)
                      at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178)
                      at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:356)
                      at java.net.Socket.connect(Socket.java:605)
                      at java.net.Socket.connect(Socket.java:554)
                      at java.net.Socket.<init>(Socket.java:431)
                      at java.net.Socket.<init>(Socket.java:210)
                      at com.example.jonas.network_connector.MainActivity$2.onClick(MainActivity.java:88)
                      at android.view.View.performClick(View.java:5637)
                      at android.view.View$PerformClick.run(View.java:22433)
                      at android.os.Handler.handleCallback(Handler.java:751)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6186)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
I/Process: Sending signal. PID: 16980 SIG: 9
Application terminated.

Since i'm new to socket programming (and android as well) I don't know how to proceed to find the error.

My manifest has the permission lines:

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
MrJonas
  • 197
  • 11

3 Answers3

3

You need to do Network work on worker thread.

btReceive.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                txtStatus.setText("Received button pressed.");
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Socket s = new Socket(SERVER_IP, PORT);
                            BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
                            final String st = input.readLine();
                            txtReceivedText.post(new Runnable(){

                                @Override
                                public void run() {
                                    txtReceivedText.setText(st);
                                }
                            });

                            s.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    }
                }).start();
            });
Sunny
  • 14,522
  • 15
  • 84
  • 129
2

android.os.NetworkOnMainThreadException

This exception tells you that you are trying to call remote in main thread. Try to use AsyncTask to call and problem should not appear again. Android OS prevents executing long running operations in main thread, because it can lock UI.

Patryk Jabłoński
  • 697
  • 10
  • 29
1

android.os.NetworkOnMainThreadException

it means your application attempts to perform a networking operation on its main thread. Run your code in AsyncTask.

Example:

 class TCPTask extends AsyncTask<Void, Void, Void>{

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... params) {
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
        }
    }

For execute the Async task:

add this code in your oncreate() method

new TCPTask().execute();
Gaurav
  • 491
  • 2
  • 8
  • 17