0

I tried to create an app to connect to a server in order to send notification each time it receive a message from the server. I've creat a simple client that's reading received message until the server disconnect. It work using a "Normal" Java but when i put the same code in a Button event in android it crash. I think that's come from android's way to treat the exceptions but i'm not sur.

Code

Start.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            String notif = "";

            try {
                //Get the server info from 2 Text Field
                socket = new Socket(IpServer.getText().toString(),Integer.parseInt(PortServer.getText().toString()));

                //While the server is connected it read
                while (socket.getInputStream().read() != -1){

                    in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                    //If the message is different to the one before
                    if(!notif.equals(notif = in.readLine())) {

                        if(!alarm.isChecked()) {

                            //Send a notification
                            createNotification(notif);

                        }else if(alarm.isChecked()){

                            //Send a notification and play a ringtone

                            createNotification(notif);

                            Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);

                            Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);

                            r.play();

                        }
                    }
                    try{

                        Thread.sleep(1000);

                    }catch(InterruptedException e){

                        error.setText("         That's wierd");

                    }
                }

                socket.close();

            }catch (UnknownHostException e) {

                error.setText("         This IP is unreachable");

            }catch (IOException e) {

                error.setText("         This IP is unreachable");

            }
        }
    });

Crash message :

    --------- beginning of crash
06-29 08:36:24.620 4325-4325/com.example.nxf44628.notificationextender E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.nxf44628.notificationextender, PID: 4325
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
        at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:110)
        at libcore.io.IoBridge.connectErrno(IoBridge.java:137)
        at libcore.io.IoBridge.connect(IoBridge.java:122)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:163)
        at java.net.Socket.startupSocket(Socket.java:592)
        at java.net.Socket.tryAllAddresses(Socket.java:128)
        at java.net.Socket.<init>(Socket.java:178)
        at java.net.Socket.<init>(Socket.java:150)
        at com.example.nxf44628.notificationextender.MainActivity$1.onClick(MainActivity.java:76)
        at android.view.View.performClick(View.java:5198)
        at android.view.View$PerformClick.run(View.java:21147)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
  • Its possible that your app crashed because you are doing a long running operation without spawning a separate thread. Unless you provide logs nothing can be said. Meanwhile, you can learn how to provide debug logs - go through [this](https://developer.android.com/studio/debug/am-logcat) – Skynet Jun 29 '18 at 08:33
  • Oh i didn't know about adb logs option ! Great – Maxime Gouet Jun 29 '18 at 08:34
  • Bingo `android.os.NetworkOnMainThreadException` - Now there are multiple ways you can solve this. Its detailed [here](https://android.jlelse.eu/8-ways-to-do-asynchronous-processing-in-android-and-counting-f634dc6fae4e) - choose the one which best fits your requirement. – Skynet Jun 29 '18 at 08:40

2 Answers2

1

The problem with your code is that it is making a connection (socket) over the main thread aka the UI thread, which is not allowed.

Instead we have to wrap the network call within a background thread, so that this does not have an impact on the app.

You have several ways to do this.

  • Using a handler.
  • Async Task
  • Intent & background service
  • Use reactive programming and all great libs associated.

Here is a basic example about Async Task

Skynet
  • 7,820
  • 5
  • 44
  • 80
0

use

<uses-permission android:name="android.permission.INTERNET"/>

in your androidManifest.xml

Here the link to a similar question

Also move all the stuff in the button listener to a thread or service.

Vall0n
  • 1,601
  • 2
  • 14
  • 19