Android live server connection status - android

Wondering if its possible to monitor constantly some wifi connection to a server (some ip and port) and display the status of the connection, that is if the server is accessible/responsive or not.
By displaying the status i mean updating some textview displaying either "server up" or "server down".
(something similar to the wifi icon next to the battery indication at the top right..)

the answer is to make a thread class, which will constantly call (with a while loop) an asynctask. The asynctask will (try to) connect to the mysql server. the connection will be successful or not and accordingly a textview or something will be updated in the UIthread (using runOnUiThread)
an example of the code for the thread:
class servlookthread extends Thread {
#Override
public void run() {
while (keeplookingserver){
lookforserver lserv = new lookforserver(); // this is the asynctask thread
try {lserv.execute().get();} catch (ExecutionException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();} //! .get() it waits until the asynctask finishes
try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();} // some delay, 4 seconds
}
return;
}
}
the keeplookingserver is a boolean, "global" variable used to control the execution of the thread.
hope this helps someone! although i think its not elegant, its working for me

Related

Tasks.await() is not returning when expected

I am trying to save data into a Firebase RealtimeDatabase.
The process of saving is fine and works just well, but I was curious about an idea I had: To force the .setValue operation into a synchronous structure. I know, that that way isn't the best one, but I wanted to try it regardless of that fact.
So I came up with this code:
Thread t1 = new Thread(){
public void run(){
try {
Tasks.await(databaseReference.child("someChild").setValue(someObject));
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("finished");
}
In theory, that code snippet is intended to first set the value in the Database, then wait for the completion of that (through the Tasks.await()), and then print out **after that* the line "finished".
I wrapped the Tasks.await()-command in a second thread because when I don't, I get an exception which says something like "Tasks.await() must not be called in the main application thread".
But when I run the whole thing, it just gets stuck at t1.join();.
When I delete the t1.join();-statement, everything works just fine, but the second Thread (t1) isn't finished before the "finished"-output is there. I know why this is like that, but I am nontheless interested in a solution to that problem.

Android Volley RequestFuture always timing out

I want to load some data on application startup that will be used by all activities.
I do this in the application's onCreate method and because I want this data to be downloaded before any activity is shown, I try to make a synchronous request using RequestFuture. However the TimeoutException is always thrown.
public void onCreate() {
super.onCreate();
appRequestQueue = Volley.newRequestQueue(this);
RequestFuture<JSONArray> requestFuture = RequestFuture.newFuture();
JsonArrayRequest request = new JsonArrayRequest(
URL,
requestFuture,
requestFuture);
appRequestQueue.add(request);
try {
JSONArray jsonArray = requestFuture.get(90, TimeUnit.SECONDS);
// Do processing. Never gets here
Log.v("*******************", "Application initialized");
} catch (JSONException je) {
} catch (InterruptedException ie) {
} catch (ExecutionException ee) {
} catch (TimeoutException te) {
// Always times out
Log.v("$$$$$$$$$$$$$$$$$$$$$$$$$", "It has timed out...");
}
What is the best way to get app-wide data keeping in mind that there is no one activity that is started first?
Yeah, according to the default behavior of the volley, the wake up notification (the delivery of the response) of the Request is posted on the Handler of the main UI thread.
So when the UI thread is blocked, the wake up notification will never be executed (also the response will never be delivered), and you'll always get a timeout.
I ran into this recently, the solution is to NOT make requests or handle them from the main thread ( UI ), it always throws a TimeoutException . Consider creating a AsyncTask and performing this request from there.
You can communicate with the MainActivity using the onPostExecute callback.
https://developer.android.com/reference/android/os/AsyncTask.html

Thread loop executes once in android

im making an app that should send a message after certain amount of time via bluetooth.
The thread works fine when i use "Log" but when i use the write function of bluetooth, it seems to executes the loop when the app wants.
Hope somebody can help me:
public class AsyncWrite extends Thread {
#Override
public void run() {
while(true) {
try {this.sleep(250);} catch (Exception E) {}
//Log.e(TAG,"Test run");
mConnectedThread.write(A);
}
}
}
I've already try using asynctask executors and handlers, the result it's the same.

Puzzle: Bluetooth data send interval shortened by half after each reconnect

I modified the standard Bluetoothchat example to send 4 bytes of data at a time to a bluetooth device every half a second. It works fine if I start the App fresh. However, there is a problem if I reconnect as follows:
While Bluetooth is connected, I click the connect button again on the menu and select the same device. This disconnects the bluetooth (not sure whether this is the right procedure to disconnect). Then, I connect again by selecting the device, and it will be reconnected. After reconnection, a very strange problem appears: instead of sending the data every half a second, it will send the data every quarter a second. If I go through the process again and reconnect, the time interval will become even shorter. It gets to a point that the bluetooth device on the receiving end can't keep up with the data. At this point, the only way out is to kill the app and restart again. Then everything becomes normal, till next time I try to reconnect again.
I have tried different things but nothing appear to fix this. For example, I made sure the thread sending the data is killed when disconnected so no multiple threads are sending the data. I was wondering whether the baud rate changed when reconnected, but then why would the baud rate affect the Thread.sleep(500); statement (which is responsible for controlling the half a second data send). Any help would be greatly appreciated.
Here is the code, the SendClass is created under the MainActivity:
class SendClass implements Runnable {
public void run() {
bytearr[0]=0;bytearr[1]=0;bytearr[2]=0;bytearr[3]=0;
while (!Thread.currentThread().isInterrupted()) {
if (mChatService==null || mChatService.getState()
!=BluetoothChatService.STATE_CONNECTED) {
continue;
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mChatService.write(bytearr);
}
}//end of run
}//end of runnable
Then under STATE_CONNECTED:
case BluetoothChatService.STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to,mConnectedDeviceName));
/*
if(sendingThread!=null){
//sendingThread.stop();
sendingThread.interrupt();
if(D) Log.i(TAG, "after sendingThread");
sendingThread = null;
}*/
sendingThread = new Thread(new SendClass());
sendingThread.start();
break;
As you can see, I tried to kill the thread before creating a new one but that didn't make any difference. Any suggestions?
You are creating a thread that never actually stops, even after you create a new thread and assign to the same variable that particular thread wont stop running.
You need to make sure that the thread will stop after it disconnects.
Here is my suggestion
Change your SendClass to:
class SendClass implements Runnable {
private boolean stopped = false;
public void setStopped(boolean s){
this.stopped = s;
}
public void run() {
bytearr[0]=0;bytearr[1]=0;bytearr[2]=0;bytearr[3]=0;
while (!Thread.currentThread().isInterrupted() && !stopped) {
if (mChatService==null || mChatService.getState() !=BluetoothChatService.STATE_CONNECTED) {
continue;
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mChatService.write(bytearr);
}
}//end of run
}//end of runnable
Then when you start your thread keep the reference to the Runnable so you can call the setStopped(true); like this
SendClass sc = new SendClass();
sendingThread = new Thread(sc);
sendingThread.start();
When you disconnect the bluetooth dont forget to call sc.setStopped(true); so your thread will finish by not going into the while.

killing asynctask when doInBackground hangs on a TCP Socket

IPStringI have a fairly simple Activity which works as follows:
in the onCreate, I call an AsyncTask TCP Socket connection to a remote server over a proprietary port, send a quick ASCII command to the server and process the response via the onPostExecute(). Works great, it's fast and functional.
However, if the remote server is down -- or I mistakenly entered in the wrong IP address for the communication -- my AsyncTask will hang with the "logging in" dialog spinning on the screen for as long as it takes for the Socket to timeout.
I've been digging away at this for the last 2 days trying to figure out how to call the cancel(), but am failing. Any suggestions?
Here's the current code:
public class Scratchpad extends AsyncTask<Object, String, String>{
private String returningResponse;
private volatile Socket socket;
#Override
protected void onPreExecute(){
//throw the "Logging In" dialog up
initializeDialog();
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
//send the ASCII result off to the function that parses through it
loginTriggerResult(result);
super.onPostExecute(result);
}
#Override
protected String doInBackground(Object... params) {
/*
* bunch of stuff goes here to strip out the proper
* values from the Object for IP address, Port number etc.
* params[0], params[1] etc.
*
*/
InetAddress serverIP = null;
String IPString = (String) params[1];
int portnumber = (Integer) params[2];
//convert the String "IPString" into an InetAddress
try {
serverIP = InetAddress.getByName(IPString);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//and then, bingo bango bongo, make the connection with the 'try':
try{
socket = new Socket(serverIP.getHostAddress(), portnumber);
//I tried this too, forcing the timeout... It crashes immediately.
//SocketAddress socketAddress = new InetSocketAddress(serverIP.getHostAddress(), portnumber);
//socket.connect(socketAddress, 3000);
Log.d("networking","Connection Completed");
//bunch of stuff goes here that happens AFTER the solid connection,
//which we never get to if the Socket fails on a "waiting to connect" thing.
//reader.close();
//outputStream.close();
}catch (SocketException e){
e.printStackTrace();
Log.w("socket","socket closed with SocketException");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.w("socket","socket closed with IOException");
}
return returningResponse; //postExecute will handle this.
}
}
I'm not getting any of the Log messages until the 3 or 4 minutes pass that the socket times out.
I'm thinking there must be a way to run a TimerTask or something OUTSIDE of the AsyncTask to track how long it's taking to make the connection (or not) and then somehow "cancel()" the running 'try' inside the AsyncTask, but I've been failing on numerous styles.
This HAS to be something that's commonly used, and there's gotta be an easy solution?
UPDATE:
The path I was heading down was trying to use the socket connection from within AsyncTask to "monitor itself", and if/when it timed out without getting a solid connection -- trigger the cancel() of the AsyncTask.
I was trying to do this from within the AsyncTask itself, with this.cancel() inside the IOException catch of the Socket timeout.
The solution so far is to implement a timer outside of the AsyncTask that launches at the same time as the AsyncTask, and call the cancel from there after however many seconds have transpired.
This solution does gracefully exit from the connection attempt, and I can put any sort of Dialog triggers or Toasts inside the onCancelled() stanza of the AsyncTask.
It doesn't crash anymore, BUT: the socket is still trying to connect in the background, even though the task is cancelled.
It definitely seems like the simplest solution (which you have tried) would be to set the timeout when calling connect. Can you post the stack trace generated when the connect with timeout fails?
What exactly is it are you trying to do? Detect when you've entered the wrong IP address or the server is down? Only show logging in for a certain amount of time? I get that you're asking how to cancel your async task, but that doesn't seem to be the root of the problem you're trying to solve.
I think MisterSquonnk is exactly right, you should just be able to set the timeout duration when call connect. You may have something else broken in your code if that timeout doesn't work. Alternatively if you just want something that lets you do your own timeout without having anything to do with socket, see below:
If you want to assume you're connection has failed in a shorter amount of time than the socket takes to time out, start a new CountDownTimer http://developer.android.com/reference/android/os/CountDownTimer.html at the same time and in the same place in your activity as you start your async task with whatever you want the timeout duration to be.
After the timer runs out (and onFinish in the timer is called), call cancel on the async task, or otherwise prevent onPostExecute from executing, and do whatever you want to do when a login attempt fails in your UI. Similarly if the login attempt succeeds before the timer runs out, cancel the timer or otherwise prevent onFinish from being called.

Categories

Resources