I'm developping an Android REST-API oriented application.
I need to create a method to check whether the server is available or not.
The problem is if you use the URL.openStream() method, there's no way to determine whether a request was successful or not.
Is there a way to do it without the need to operate of performing a full HttpURLConnection and read the return code?
You can use TCP Sockets
SocketAddress socketAddress = new InetSocketAddress(address, port);
try {
int timeout = 2000;
socket.connect(socketAddress, timeout);
}
catch (IOException e) {
return false;
}
finally {
if (socket.isConnected()) {
try {
socket.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Related
I have implemented Android ServerSocket to work with a payment device in semi integrated mode. Payment device is Android based so it will open a server socket and listens for incoming requests on a fixed port. I have also created a dummy clientApp where I send data/request to payment app and it sends the response back to cleint app. This part works.
The problem arises when I send the same request via an app like Paket Sender. In this case the request is received on server side but when I send the response back to client (Packet Sender) it does not receive anything when connection is active.
Below is my code snippet where I read the data and then send the data.
the part where I create a server socket
ServerSocket serverSocket = new ServerSocket(SERVER_PORT);
Socket socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
Then the communication thread
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
//here the clientSocket is used to listen to incoming messages from client
this.clientSocket = clientSocket;
//here this tempClientSocket is used to send messages back to client through sendMessage() methos which is defined below.
tempClientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
showMessage("Error Connecting to Client!!");
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
//we receive the incoming message in this read variable and from here we parse it and send the request to PayWorks SDK.
String read = input.readLine();
Log.e("READ"," Read->"+read);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
* Using below method we send the message back to the client. We are having problems in this part when client is an application
* like Packet Sender.
* Because we do not know how the underlying parsing of these apps works hence we cant debug it.
* What we have made sure is that result 'message' variable is
* correct here and that tempClientSocket is not null.
* But after that we just send the message over the socket and we do not have further control over it.
* This method works if client is implemented in mobile and have similar implemementation of client code as mentioned on
* android developer Socket implementation guide.
*
private void sendMessage(final String message) {
try {
Log.e("MESSAGES","Message is->"+message);
if (null != tempClientSocket) {
new Thread(new Runnable() {
#Override
public void run() {
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(tempClientSocket.getOutputStream())),
true);
} catch (IOException e) {
e.printStackTrace();
}
out.println(message);
}
}).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Can someone help me figuring out what I need to change in sendMessage() method above so that even in applications like Packet Sender I can see the data sent back by the server.
PS- I have tried most of the solutions available on SO regarding this and hence posting this as a last resort.
I used Socket to communicate with Client. I've problem for setting the timeout for OutputStream. The Socket itself already set the timeout. When I didn't set the timeout for OutputStream, when the internet connection is shut down at OutputStream out = socket.getOutputStream(), the IOException will thrown after 15 minutes. It will affect the user experience itself.
Socket.java
// Create an SSLContext that uses our TrustManager
final SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
SSLSocket socket = null;
try{
SSLSocketFactory sslsocketfactory = context.getSocketFactory();
socket = (SSLSocket) sslsocketfactory.createSocket();
socket.connect(new InetSocketAddress(<dstAddress>, <dstPort>), <timeout>);
// Here is the point when the internet connection is loss
OutputStream out = socket.getOutputStream();
out.write(BytesUtil.hexStringToBytes(<requestParams>));
out.flush();
} catch(SocketTimeoutException se) {
se.printStackTrace();
} catch (IOException e) {
// Will thrown after 15 minutes
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
// close socket
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
See Socket and ServerSocket. Both classes have a setSoTimeout method to specify the maximum time to wait when waiting for connections or waiting to receive data. When that time has elapsed, the socket throws a SocketTimeoutException that you can handle with your error message or however you want.
You have to call setSoTimeout() before performing the actions you want to have a timeout.
Prior to
while ((numberReceived = socketInputStream.read(buffer)) != -1) {
//You'll need to call
socket.setSoTimeout(2000);
And then add a catch(SocketTimeoutException) section to the try/catch block you already have.
I have a PHP webpage that insert a line in MySQL. What i want to do, is just to connect my android app on this page (no response from the server).
I try to connect from a service and i've heard I should use a thread to connect but it still doesn't work...
Here is my code :
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
try {
HttpUriRequest request = new HttpGet("http://localhost:8888/everbattery/post_sql.php");
HttpClient httpclient = new DefaultHttpClient();
httpclient.execute(request);
}
catch (ClientProtocolException E){}
catch (IOException E) {}
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
Any ideas ? I've spend most of my afternoon on that and i'm going crazy ...
You can't go for localhost in your app.
Try putting actual IP of the machine the server is running on.
You can get to know it by using ipconfig / ifconfig.
I have a problem! I have a connection with a php page to connect with database and the method works fine on Froyo, but doesn't work on newer versions of Android. What is the problem?
public static String interact(String request){
String result="test";
String site = "http://xxxx.net:nnn/xxx";
URL url = new URL(site);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.connect();
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
wr.write(request);
wr.flush();
wr.close();
Scanner in = new Scanner(connection.getInputStream());
while(in.hasNextLine())
result+=in.nextLine();
connection.disconnect();
return result;
}
catch (UnknownHostException e) {
return e.getMessage();
} catch (IOException ex) {
return ex.getMessage();
}
catch (Exception ex){
return ex.getMessage();
}
}
I need to send data and get response, but it just gives me null on newer Android than 2.2.
you are running Network Request on main thread.
Android >=3.0 does not alow this. you need to use AsyncTask to call Network Request
Yes this is not allowed on version lower than 3.0. however you can override the rules by doing some setting bypass but at the very least don't do that as it might give app-crash to you.
I suggest to raise the level of your min-SDK level.
I have searched in Google. In Android 2.2 and sdk 8 how can I use SSID in a List in Android ?
By using SSID should get specific wifi enabled device properties by programmatically. With that help, should transfer the data between two Wifi enabled devices in Android.
To send data in a meaningful manner between two Android devices you would use a TCP connection. To do that you need the ip address and the port on which the other device is listening.
Examples are taken from here.
For the server side (listening side) you need a server socket:
try {
Boolean end = false;
ServerSocket ss = new ServerSocket(12345);
while(!end){
//Server is waiting for client here, if needed
Socket s = ss.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter output = new PrintWriter(s.getOutputStream(),true); //Autoflush
String st = input.readLine();
Log.d("Tcp Example", "From client: "+st);
output.println("Good bye and thanks for all the fish :)");
s.close();
if ( STOPPING conditions){ end = true; }
}
ss.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
For the client side you need a socket that connects to the server socket. Please replace "localhost" with the remote Android devices ip-address or hostname:
try {
Socket s = new Socket("localhost",12345);
//outgoing stream redirect to socket
OutputStream out = s.getOutputStream();
PrintWriter output = new PrintWriter(out);
output.println("Hello Android!");
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
//read line(s)
String st = input.readLine();
//. . .
//Close connection
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
For data Transfer between 2 devices over the wifi can be done by using "TCP" protocol. Connection between Client and Server requires 3 things
Using NSD Manager, Client device should get server/host IP Address.
Send data to server using Socket.
Client should send its IP Address to server/host for bi-directional communication.
For faster transmission of data over wifi can be done by using "WifiDirect"
which is a "p2p" connection. so that this will transfer the data from one to other device without an Intermediate(Socket). For example, see this link in google developers wifip2p and P2P Connection with Wi-Fi.
Catch a sample in Github WifiDirectFileTransfer