Reputation: 111
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
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
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