0

I've made a simple chat app for desktop use in Java along with a server. Now, I rebuilt the desktop app into an android one. The only problem is I can't get it to connect to the server. It didn't work in the background so I tried with a button but still no result.

I am running the server in eclipse and the app in an android studio with an emulator.

IMPORTANT NOTE: It shows error:

08-01 18:00:57.255 8914-8914/com.example.android.chatnow E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.chatnow, PID: 8914
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.chatnow/com.example.android.chatnow.MainActivity}: android.os.NetworkOnMainThreadException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1450)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:355)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:357)
        at java.net.Socket.connect(Socket.java:616)
        at java.net.Socket.connect(Socket.java:565)
        at java.net.Socket.<init>(Socket.java:445)
        at java.net.Socket.<init>(Socket.java:217)
        at com.example.android.chatnow.MainActivity.setUpNetworking(MainActivity.java:29)
        at com.example.android.chatnow.MainActivity.onCreate(MainActivity.java:17)
        at android.app.Activity.performCreate(Activity.java:7009)
        at android.app.Activity.performCreate(Activity.java:7000)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6494) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

Here is the code:

package com.example.android.chatnow;
import java.io.*;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import java.net.*;
public class MainActivity extends AppCompatActivity {
    BufferedReader reader;
    PrintWriter writer;
    Socket sock;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Thread readerThread = new Thread(new IncomingReader());
        readerThread.start();
    }
    public void onSendMessage(View view) {
        EditText messageView = (EditText)findViewById(R.id.message);
        String messageText = messageView.getText().toString();
        //writer.println(": " +messageText);
        //writer.flush();
    }
    public void setUpNetworking(View view) {
        try {
            sock=new Socket("10.0.2.2", 5000);
            InputStreamReader streamReader = new InputStreamReader(sock.getInputStream());
            reader = new BufferedReader(streamReader);
            writer = new PrintWriter(sock.getOutputStream());
            Log.d("NiceTag", "Net established");
        }catch (Exception ex){
            ex.printStackTrace();
            Log.d("NiceTag", "Net failed");
        }
    }
    public class IncomingReader implements Runnable{
        public void run() {
            String message;
            try {
                while ( (message=reader.readLine())!=null) {
                    TextView messageView = (TextView)findViewById(R.id.displaymessage);
                    messageView.append( message + '\n');
                }
                System.out.println("!while");
            } catch(Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}

And the XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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=".MainActivity">

    <TextView
        android:id="@+id/displaymessage"
        android:layout_width="262dp"
        android:layout_height="401dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="40dp"
        android:ems="10"
        android:inputType="textPersonName"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/displaymessage" />

    <Button
        android:id="@+id/sendbutton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="36dp"
        android:text="Send"
        android:onClick="onSendMessage"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.469"
        app:layout_constraintStart_toEndOf="@+id/message"
        app:layout_constraintTop_toBottomOf="@+id/displaymessage" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="Connect"
        android:onClick="setUpNetworking"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/displaymessage"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Also, the manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.chatnow">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <application

        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

P.S. Server and emulator are running on the same device

Kira02
  • 58
  • 2
  • 8

3 Answers3

1

I solved it. I modified Exception to IOException. After thet, I created a Thread for setUpNetworking! Thanks all for your answers! :)

Kira02
  • 58
  • 2
  • 8
0

Assuming, you have your Android app running in the Emulator on your local machine and server running on the same machine, then localhost won't refer to your server application. If you want to refer to the server application, then you should call the following IP address: 10.0.2.2 from the emulator running on the same machine as server.

When you call the server from the physical device, then find your IP address via ifconfig command (or ipconfig on Windows) in terminal, connect the mobile device to the same local network as server via WiFi and use appropriate IP address in your Android app.

EDIT

After your last edit, problem is more clear. You have two issues:

  • setting the wrong host - it should be 10.0.2.2 instead of localhost
  • calling request in the main thread - request should be called in a separate thread - e.g. with the AsyncTask (see official docs to find out how to use this class)
Piotr Wittchen
  • 3,853
  • 4
  • 26
  • 39
0

At first I executed your code and I ended up with the following exception:

android.os.NetworkOnMainThreadException which means that you have to migrate your code from your main thread to a worker or background thread.

One way to do that is to introduce an AsyncTask as the following:

private class ConnectSimpleServerTask extends AsyncTask<Void, Void, Void> {
    private Socket sock;

    private ConnectSimpleServerTask(Socket sock) {
        this.sock = sock;
    }

    @Override
    protected Void doInBackground(Void... voids) {
        try {
            sock=new Socket("10.0.2.2", 5000);
            InputStreamReader streamReader = new InputStreamReader(sock.getInputStream());
            reader = new BufferedReader(streamReader);
            writer = new PrintWriter(sock.getOutputStream());
            Log.d("NiceTag", "Net established");
        }catch (Exception ex){
            ex.printStackTrace();
            Log.d("NiceTag", "Net failed");
        }
        return null;
    }
}

and in your setUpNetworking, do this:

public void setUpNetworking(View view) {
        new ConnectSimpleServerTask(sock).execute();
    }

This is just a starting point, you can modify your AsyncTask as you please. Then, after executing with the current worker Thread,

the socket obj is still being null which means that is an issue with host or the port.

I found this answer that might help you on setting up the right host and port, take a look at it.

Red M
  • 2,609
  • 3
  • 30
  • 50
  • 1
    haha I just figured it out by myself 2 minutes ago :) . Thanks very much for answer ! Also, i printed the exception in a wrong way. I should have used IOException instead. – Kira02 Aug 01 '18 at 18:22