F.Fipoo
F.Fipoo

Reputation: 111

Android socket connect in background

What should I do to keep the server running and listening when the application is in the background?

I'm currently throwing an error: I can't make a connection because the target computer is actively refusing to connect.

I have server on android and client on pc/python.

anyone could explain I will be grateful. Code with my server.

public class MainActivity extends Activity {

private ServerSocket serverSocket;

Handler updateConversationHandler;

Thread serverThread = null;

private TextView text;

public static final int SERVERPORT = 8080;

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    text = (TextView) findViewById(R.id.textView);

    updateConversationHandler = new Handler();

    this.serverThread = new Thread(new ServerThread());
    this.serverThread.start();

}

@Override
protected void onStop() {
    super.onStop();
    try {
        serverSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

class ServerThread implements Runnable {

    public void run() {
        Socket socket = null;
        try {
            serverSocket = new ServerSocket(SERVERPORT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        while (!Thread.currentThread().isInterrupted()) {

            try {

                socket = serverSocket.accept();

                CommunicationThread commThread = new CommunicationThread(socket);
                new Thread(commThread).start();

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

class CommunicationThread implements Runnable {

    private Socket clientSocket;

    private BufferedReader input;

    public CommunicationThread(Socket clientSocket) {

        this.clientSocket = clientSocket;

        try {

            this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));

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

    public void run() {

            try {

                String read = input.readLine();

                updateConversationHandler.post(new updateUIThread(read));

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

    }

}

class updateUIThread implements Runnable {
    private String msg;

    public updateUIThread(String str) {
        this.msg = str;
    }
    @Override
    public void run() {
        if (msg == null) {
            text.setText(msg);
        }
        else{
            text.setText(msg);
            createNotification();
        }
    }
}
void createNotification() {

    Intent intent = new Intent(this, MainActivity.class);
    PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);

    Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);

    Notification noti = new NotificationCompat.Builder(this)
            .setContentTitle("NOTIFICATION")
            .setContentText("NOTIFICATION")
            .setTicker("NOTIFICATION")
            .setSmallIcon(android.R.drawable.ic_dialog_info)
            .setLargeIcon(icon)
            .setAutoCancel(true)
            .setContentIntent(pIntent)
            .build();

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

    notificationManager.notify(0, noti);
}}

Upvotes: 1

Views: 6117

Answers (2)

from56
from56

Reputation: 4127

Are you testing this on a local area network or through the internet(WAN)?

It must be taken into account that currently many mobile phone providers do not assign public IP addresses to the connected devices, they assign private IP and therefore the device can not act as a server due its ports are inaccessible from the WAN

Upvotes: 0

Hugou
Hugou

Reputation: 86

To perform background tasks in Android you should use Services.
A service for the Server would look like:

public class MyService extends Service {

    public static final String START_SERVER = "startserver";
    public static final String STOP_SERVER = "stopserver";
    public static final int SERVERPORT = 8080;

    Thread serverThread;
    ServerSocket serverSocket;

    public MyService() {

    }

    //called when the services starts
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //action set by setAction() in activity
        String action = intent.getAction();
        if (action.equals(START_SERVER)) {
            //start your server thread from here
            this.serverThread = new Thread(new ServerThread());
            this.serverThread.start();
        }
        if (action.equals(STOP_SERVER)) {
            //stop server
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException ignored) {}
            }
        }

        //configures behaviour if service is killed by system, see documentation
        return START_REDELIVER_INTENT;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    class ServerThread implements Runnable {

        public void run() {
            Socket socket;
            try {
                serverSocket = new ServerSocket(SERVERPORT);
            } catch (IOException e) {
                e.printStackTrace();
            }
            while (!Thread.currentThread().isInterrupted()) {

                try {

                    socket = serverSocket.accept();

                    CommunicationThread commThread = new CommunicationThread(socket);
                    new Thread(commThread).start();

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

    class CommunicationThread implements Runnable {

        private Socket clientSocket;

        private BufferedReader input;

        public CommunicationThread(Socket clientSocket) {

            this.clientSocket = clientSocket;

            try {

                this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));

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

        public void run() {

            try {

                String read = input.readLine();

                //update ui
                //best way I found is to save the text somewhere and notify the MainActivity
                //e.g. with a Broadcast
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

In your Activity, you can start the Service by calling:

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

    //will start the server
    Intent startServer = new Intent(this, MyService.class);
    startServer.setAction(MyService.START_SERVER);
    startService(startServer);

    //and stop using
    Intent stopServer = new Intent(this, MyService.class);
    stopServer.setAction(MyService.STOP_SERVER);
    startService(stopServer);
}

also you have to declare the Internet permission in your AndroidManifest.xml. Add these to lines above of the tag:

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

Upvotes: 1

Related Questions