ANDROID - Connection not staying when activity is changed - android

I am developing an app that logs onto a tomcat server.
I am using a HTTP GET request to do so, and upon successful connection,
the message is displayed via a buffered stream.
The following code, is used to connect.
public String getInternetData() throws Exception {
BufferedReader in = null;
String data = null;
try {
HttpClient client = new DefaultHttpClient();
client.getConnectionManager().getSchemeRegistry().register(getMockedScheme());
URI website = new URI("https://ts.rks.com:8443/kss/login?username=hydm&password=pw1234");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
response.getStatusLine().getStatusCode();
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) != null) {
sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;
} finally {
if (in != null) {
try {
in.close();
return data;
} catch (Exception e) {
Log.e("GetMethodLogin", e.getMessage());
}
}
}
This is the code that is activated when the user logs in via a login activity.
When I go back to the menu screen and try to run another activity that requires the user
to be logged in, it says that the user is not logged in.
Is the connection being disconnected when the user moves away from the activity or am I not establishing the connection correctly.

There are actually two things you need to change, not just one.
Anything that you need to have persistent across Activities should be done in a Service, not in the code of an Activity.
Second, on recent Android releases, all networking must be done from background threads, rather than the UI thread (there was always a recommendation against UI thread networking, but now it triggers an exception). Just putting the code in a Service does not mean it is in another thread.
So the answer is that you should be doing this using one of the background threading mechanisms, and doing that within a Service.

The connection will not persist when the activity is moved to the background. I cannot tell from your posted code, but I believe you should be using an AsyncTask for this connection. This is coming from my experience pulling HTML source from a link.
This question may answer yours: What to do with AsyncTask in onPause()?

Related

Making chat app

I want to do a chat application and I found this code on GitHub : https://github.com/Pirngruber/AndroidIM. And author created a function to send a message which looks like this
public String sendHttpRequest(String params)
{
URL url;
String result = new String();
try
{
url = new URL(AUTHENTICATION_SERVER_ADDRESS);
HttpURLConnection connection;
connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
PrintWriter out = new PrintWriter(connection.getOutputStream());
out.println(params);
out.close();
BufferedReader in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
result = result.concat(inputLine);
}
in.close();
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
if (result.length() == 0) {
result = HTTP_REQUEST_FAILED;
}
return result;
}
Where private static final String AUTHENTICATION_SERVER_ADDRESS = "http://192.168.0.102/android-im/index.php";
And also here he explained how to make it run
https://code.google.com/archive/p/simple-android-instant-messaging-application/
So, my question is that: As I understood author sends all messages to his server and after this server sends them to user. So, if PC will be turned off server won't work and his chat won't work too, is it right? If yes, can somebody explain me how to do a chat app without server?
Thank you
Yes, seems like it requires a server to be online at all times. But that's how all modern chat applications on smartphones work (Telegram, Whatsapp, Threema, all google chats...). Without a server you would rely on the fact that both smartphones are online at the same time in order to establish a direct connection. This is a huge disadvantage and works against any power-saving features of the mobile OS. Also two parties can hardly communicate if they are always online at different times.
So essentially you need to decide for yourself whether you really want a peer-to-peer or a server-based chat. Just remember that even in case of P2P, you will have to figure out the IP addresses of the other chat clients. And then you'll probably have to use some sort of server, again.
What you need is a P2P chat implementation, you can use WIFI direct for that in Android. Checkout this code: https://github.com/life0fun/wifi-direct-chat
Usually the chat apps need to have a central server to receive the messages and send it to the correct nodes. That code you paste is that kind of implementation.

Is android epoch time the same in all devices

I made an app that syncs data data across devices based on an epoch time. I am currently getting this epoch time by using rest api on a server by using httpurlconnection as follows:
public static String getTime(String time){
InputStream is = null;
BufferedReader bufferedReader = null;
HttpURLConnection urlConnection = null;
try{
URL url = new URL(SERVERURL);
urlConnection = (HttpURLConnection) url.openConnection();
is = urlConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(is,"UTF-8"));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while((line = bufferedReader.readLine()) != null){
stringBuilder.append(line);
}
JSONObject jsonObject = new JSONObject(stringBuilder.toString());
return jsonObject.getString("time");
}
catch(JSONException e){
Log.d("getTime","json object creation failed");
}
catch(IOException e){
Log.d("getTime", "couldn't get time from server");
}
finally {
try {
if(urlConnection != null){
urlConnection.disconnect();
}
if(bufferedReader != null) {
bufferedReader.close();
}
if(is != null){
is.close();
}
}
catch(IOException e){
Log.d("async getGameName","io exception closing buffer");
}
}
return time;
}
so that all devices are getting a timestamp from one known source. This method runs in a background service so it does not slows down the app responsiveness, but it is not yielding a good user experience because I need this timestamp to display information to the user and the http request takes long. Some times up to a minute because this depends on the network connectivity, so I wanted to ask if local epoch time is the same across all android devices and if it is what is the best way to get an epoch timestamp on android? Thanks in advance.
The epoch time depends on the time synchronization of a device, so two devices might have different values for it.
Also, fetching time information from a REST endpoint does not seem like the most efficient way, as you are also introducing potential delays on the API endpoint in addition to general network latency.
Since Android devices use an NTP server of sorts to get their time, why don't you get time information from the device itself and converting to epoch? The device itself is already getting updated time information so you might just as well use that.
If you want to get the current epoch value from the device itself you can use [currentTimeMillis()][1]:
System.currentTimeMillis()/1000
This returns the number of milliseconds, so to get an epoch value, which is in seconds, just divide by 1000.

Android HttpDefaultClient times out only after another device makes a similar but not identical request

Some quick background. We have multiple devices running a scanner app which checks against a database to see whether an id has been scanned in or not. I can scan in with Device A as many times as I like without issue. I then pick up Device B and scan in, also as many or few times as I like. If I pick Device A back up and scan, the HttpClient will hang for approximately 60 seconds refusing to send any further requests. The code below has commented the point of failure.
// Asynchronous get request
private class aGETRequest extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
client.setKeepAliveStrategy(null);
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse httpResponse = client.execute(httpGet); //Hangs Here
HttpEntity httpEntity = httpResponse.getEntity();
InputStreamReader isr = new InputStreamReader(httpEntity.getContent());
BufferedReader buffer = new BufferedReader(isr);
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
httpEntity.consumeContent();
isr.close();
} catch (Exception e) {
e.printStackTrace();
}
httpGet.abort();
client.getConnectionManager().shutdown();
}
return response;
}
#Override
protected void onPostExecute(String result) {
results(result);
}
}
The client hangs and even snooping traffic shows no requests sent at all from Device A after the failure. You ready for the best part? If the devices are going through a Proxy server, it works. W.T.F?
Android is java 6 compat . right.
BufferedReader on java 7 makes me nervous and the while read loop appears to be whats hanging.....
I would try a different different read loop class thats solid on java 6 or i would find someone else's pattern for httpclient that's solid.
My wild guess is that your code is never getting out of the following...
while ((s = buffer.readLine()) != null)
Maybe the server is returing chunked encoding or something like that with a diff protocol ( pattern of length=0 followed by \r\n or something.

Read data from webpage in Android

I use this code for read data from html page and put in to webview
public class MainActivity extends Activity {
public WebView objwebview ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
objwebview = (WebView)findViewById(R.id.webView1);
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://www.google.com");
try
{
HttpResponse response = client.execute(request);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line;
StringBuilder str = new StringBuilder();
while((line = reader.readLine()) != null) {
str.append(line);
}
objwebview.loadData(str.toString(), "text/html", "UTF-8");
}
catch(Exception e)
{
e.printStackTrace();
objwebview.loadData(e.toString(), "text/html", "UTF-8");
}
but when I run that ,I give this error ("android.os.networkonmainthreadexception")
how can I fix that?
You are running your networking code on the main thread in Android. Read this to find some partial answers to your problem.
The basic idea is that if you perform synchronous reads that do not immediately return (i.e., things that take a long time, such as network operations), you need to do so on another thread, and then communicate the results back to the GUI.
You have a few options to do this: you can use an AsyncTask, which allows you to painlessly publish updates to the UI, or you can use a background Service along with an associated communication (either via AIDL or a simpler Message and Handler).
you are accessing network connection in main thread. paste the following lines beneath setContentView(your_layout);
// Allow network access in the main thread
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

How to disconnect an HttpUrlConnection on HTC (Froyo and below) phones?

I need to disconnect a long polling http request from the client side in some cases. The relevant part of the HttpUrlConnection I make to the server is as follows (all the code below is within a Thread's run() method):
try {
URL url = new URL(requestURL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setConnectTimeout(5 * 1000);
connection.setReadTimeout(60 * 1000);
connection.setRequestMethod("GET");
// read the output from the server
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line + "\n");
}
Log.d(TAG, stringBuilder);
} catch (IOException ioe) {
Log.e(TAG, ioe);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
This is how I first initiate, then (after a second delay) try to cancel the request:
pollThread = new PollThread();
pollThread.start();
Log.d(TAG, "pollThread started");
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
pollThread.cancelRequest();
Log.d(TAG, "pollThread presumably cancelled");
}
}, 1000);
And this is what the cancelRequest() method looks like:
public void cancelRequest() {
if (connection != null) {
connection.disconnect();
}
}
So essentially,
I initiate a HttpUrlConnection with a get request, with 1 minute read timeout
Then after one second, I try to cancel the earlier request
The expected outcome is that the connection should throw an IOException when I call connection.disconnect()
And this is exactly what happens on various emulators (2.2 - 4.0.3), a Motorola Atrix (2.3.7) and a Samsung Note (4.0.1). But on some HTC devices running 2.2, the request will stay alive and it will recieve the response, despite the fact that I explicitly terminated the connection. I verified this with an HTC Desire and an HTC Wildfire.
What's going on here? How can I cancel such a request safely on all devices running 2.2+?
For your convenience, the whole code is available here, should you like to do a test drive yourself: https://gist.github.com/3306225
What's going on here?
This is a known bug in earlier android release (Froyo 2.2) which, in sort, sockets can not be closed asynchronously by other threads, and has been fixed in Gingerbread 2.3:
Issue 11705: impossible to close HTTP connection using HttpURLConnection
How can I cancel such a request safely on all devices running 2.2+?
Comments from project member in that link:
The best approximation of this that will work in current releases is to set read and connect timeouts on the HTTP connection.
Hope that helps.
Actually, I would recommend you to use Apache HttpClient lib, instead of the default supplied with android.
You can download it from: http://code.google.com/p/httpclientandroidlib/
If you want to go "all the way", you can also use AndroidHttpClient "that is configured with reasonable default settings and registered schemes for Android" and could also support cookies. You can download it from here (I can't remember when I found the original one...)
This is how you use a "Get" call, I guess you can figure out the rest:
InputStream isResponse = null;
HttpGet httpget = new HttpGet(strUrl);
HttpResponse response = getHttpClient().execute(httpget);
HttpEntity entity = response.getEntity();
isResponse = entity.getContent();
responseBody = convertStreamToString(isResponse);
and
/**
* #return the mClient
*/
protected AndroidHttpClient getHttpClient() {
if (mClient == null)
mClient = AndroidHttpClient.newInstance(mCookieStore);
return mClient;
}
To close the connction:
getHttpClient().close();

Categories

Resources