-2

I am new to Android programming.

I'm trying to make a very simple client / server TCP communication in eclipse. Server side uses a java class, and client side an Android app. I start the app from eclipse, not on an emulator but on a USB connected phone.

The problem. When I remove the INTERNET permission line of code from xml manifest file, the app doesn't crash, but it also doesn't connect (no message in the server console). But if I do put the INTERNET permission line of code in, the app crashes with message "Unfortunately APP_NAME has stopped".

Can anyone please point out what am I missing?

The code is as follows:

Server (java) class:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Main {

    private static ServerSocket serverSocket = null;
    private static Socket clientSocket;
    private static InputStreamReader inputStreamReader;
    private static BufferedReader bufferedReader;
    private static String message;

    public static void main(String[] args) {

        try {
            serverSocket = new ServerSocket(4444);  //Server socket
        } catch (IOException e) {
            System.out.println("Could not listen on port: 4444");
        }

        System.out.println("Server started. Listening to the port 4444");

        while (true) {
            try {
                clientSocket = serverSocket.accept();   //accept the client connection
                inputStreamReader = new InputStreamReader(clientSocket.getInputStream());
                bufferedReader = new BufferedReader(inputStreamReader); //get the client message
                message = bufferedReader.readLine();

                System.out.println(message);
                inputStreamReader.close();
                clientSocket.close();

            } catch (IOException ex) {
                System.out.println("Problem in message reading");
            }
        }

    }
}

Client (android) activity file:

package com.example.simpleclient;


import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class SimpleClientActivity extends Activity {

    private Socket client;
    private PrintWriter printwriter;
    private EditText textField;
    private Button button;
    private String messsage;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        textField = (EditText) findViewById(R.id.editText1); //reference to the text field
        button = (Button) findViewById(R.id.button1);   //reference to the send button

        //Button press event listener
        button.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                messsage = textField.getText().toString(); //get the text message on the text field
                textField.setText("");      //Reset the text field to blank

                try {

                    client = new Socket("127.0.0.1", 4444);  //connect to server
                    printwriter = new PrintWriter(client.getOutputStream(), true);
                    printwriter.write(messsage);  //write the message to output stream

                    printwriter.flush();
                    printwriter.close();
                    client.close();   //closing the connection

                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

    }
}

Client xml manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.simpleclient"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".SimpleClientActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

--Edit-- LogCat:

 01-21 21:40:55.012: D/libEGL(17722): loaded /vendor/lib/egl/libEGL_adreno.so
01-21 21:40:55.022: D/libEGL(17722): loaded /vendor/lib/egl/libGLESv1_CM_adreno.so
01-21 21:40:55.042: D/libEGL(17722): loaded /vendor/lib/egl/libGLESv2_adreno.so
01-21 21:40:55.042: I/Adreno-EGL(17722): <qeglDrvAPI_eglInitialize:316>: EGL 1.4 QUALCOMM build:  (CL4169980)
01-21 21:40:55.042: I/Adreno-EGL(17722): OpenGL ES Shader Compiler Version: 17.01.10.SPL
01-21 21:40:55.042: I/Adreno-EGL(17722): Build Date: 09/26/13 Thu
01-21 21:40:55.042: I/Adreno-EGL(17722): Local Branch: 
01-21 21:40:55.042: I/Adreno-EGL(17722): Remote Branch: 
01-21 21:40:55.042: I/Adreno-EGL(17722): Local Patches: 
01-21 21:40:55.042: I/Adreno-EGL(17722): Reconstruct Branch: 
01-21 21:40:55.163: D/OpenGLRenderer(17722): Enabling debug mode 0
01-21 21:40:57.875: D/AndroidRuntime(17722): Shutting down VM
01-21 21:40:57.875: W/dalvikvm(17722): threadid=1: thread exiting with uncaught exception (group=0x4190a898)
01-21 21:40:57.885: E/AndroidRuntime(17722): FATAL EXCEPTION: main
01-21 21:40:57.885: E/AndroidRuntime(17722): android.os.NetworkOnMainThreadException
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1144)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at libcore.io.IoBridge.connect(IoBridge.java:112)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.Socket.startupSocket(Socket.java:566)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.Socket.tryAllAddresses(Socket.java:127)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.Socket.<init>(Socket.java:177)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.net.Socket.<init>(Socket.java:149)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at com.example.simpleclient.SimpleClientActivity$1.onClick(SimpleClientActivity.java:41)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.view.View.performClick(View.java:4475)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.view.View$PerformClick.run(View.java:18786)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.os.Handler.handleCallback(Handler.java:730)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.os.Looper.loop(Looper.java:137)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at android.app.ActivityThread.main(ActivityThread.java:5419)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.lang.reflect.Method.invokeNative(Native Method)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at java.lang.reflect.Method.invoke(Method.java:525)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
01-21 21:40:57.885: E/AndroidRuntime(17722):    at dalvik.system.NativeStart.main(Native Method)
01-21 21:45:57.988: I/Process(17722): Sending signal. PID: 17722 SIG: 9
Vlad
  • 820
  • 10
  • 29

1 Answers1

1

You should wrap your networking code in background thread or in AsyncTask class, because networking operations in main thread are not allowed in android.

For example your code for async task should look like this

private class LongOperation extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        try {

                client = new Socket("127.0.0.1", 4444);  //connect to server
                printwriter = new PrintWriter(client.getOutputStream(), true);
                printwriter.write(messsage);  //write the message to output stream

                printwriter.flush();
                printwriter.close();
                client.close();   //closing the connection

            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "Executed";
    }

    @Override
    protected void onPostExecute(String result) {
        TextView txt = (TextView) findViewById(R.id.output);
        txt.setText("Executed"); // txt.setText(result);
        // might want to change "executed" for the returned string passed
        // into onPostExecute() but that is upto you
    }

    @Override
    protected void onPreExecute() {}

    @Override
    protected void onProgressUpdate(Void... values) {}
}

and starting your async task will look like this

package com.example.simpleclient;


import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class SimpleClientActivity extends Activity {

    private Socket client;
    private PrintWriter printwriter;
    private EditText textField;
    private Button button;
    private String messsage;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        textField = (EditText) findViewById(R.id.editText1); //reference to the text field
        button = (Button) findViewById(R.id.button1);   //reference to the send button

        //Button press event listener
        button.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                messsage = textField.getText().toString(); //get the text message on the text field
                textField.setText("");      //Reset the text field to blank

                new LongOperation().execute("");
        });

    }
}

You can define your async task right within your activity

Sergey Pekar
  • 8,555
  • 7
  • 47
  • 54