I am newbie in android programming. I have to make an app for my thesis. So i made the program and test it on VM and all was fine, but when i tried to run it on real device the program did not work. My project is to make an app that reads data from Arduino and plot them on a graph. When i test it on real device my app could not read the data. From the side of Arduino i saw that the connection was established.
Thank you for any advice-help.
MY code for connection is:
private class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
return downloadContent(params[0]);
} catch (IOException e) {
return "Unable to retrieve data. URL may be invalid.";
}
}
#Override
protected void onPostExecute(String result) {
// Toast.makeText(graphActivity.this, result, Toast.LENGTH_LONG).show();
textStatus.setText(result);
// myNum= Double.parseDouble(result);
// mytime= mytime+1;
// series.appendData(new DataPoint(mytime*1d ,myNum),true,28800);
}
}
private String downloadContent(String myurl) throws IOException {
InputStream is = null;
int length = 500;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
int response = conn.getResponseCode();
Log.d(TAG, "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = convertInputStreamToString(is, length);
return contentAsString;
} finally {
if (is != null) {
is.close();
}
}
}
public String convertInputStreamToString(InputStream stream, int length) throws IOException, UnsupportedEncodingException {
reader = new InputStreamReader(stream);
char[] buffer = new char[length];
reader.read(buffer);
return new String(buffer);
}
I wanted to say that the problem solved. The code runs perfect with no changes. The problem was from the arduino side. I made some changes to arduino code and BOOM... it works :D :). If someone want to use the code its ok. Runs either on AVD either on real device.
Related
In my following code I am trying to retrieve some JSON data by passing an URL. It works fine but does take some time in fetching data from the Internet. Even though the data isn't that bulky but still it takes like few seconds and then I can see data in log. But I really want to improve the speed with which I could improve retrieving data from internet.
public class DownloadData extends AsyncTask<String, Void, String> {
private static final String TAG = "DownloadData";
#Override
protected String doInBackground(String... strings) {
try {
URL url = new URL(strings[0]);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
String result = "";
int data;
data = inputStreamReader.read();
while (data != -1) {
char currentChar = (char) data;
result += currentChar;
data = inputStreamReader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "Failed";
}
#Override
protected void onPostExecute(String s) {
Log.d(TAG, "downloaded JSON Data: " + s);
}
}
Dont read characters one by one. Takes too much time. Use .readLine() instead.
Dont use string concatenation as that takes a lot of time too. Instead use a StringBuilder to add the lines to.
I have a problem. I'm trying to execute POST method to my Node.js server. After POST method I'm getting all the data in server but then my app isn't responding a few seconds. Is there some bugs in my code?
My POST method:
public static void setTemp(String address, String hot, String cold) throws IOException
{
URL url = new URL(address); //in the real code, there is an ip and a port
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
try {
conn.connect();
JSONObject jsonParam = new JSONObject();
jsonParam.put("hot", hot);
jsonParam.put("cold", cold);
DataOutputStream os = new DataOutputStream(conn.getOutputStream());
os.writeBytes(jsonParam.toString());
os.flush();
os.close();
Log.i("STATUS", String.valueOf(conn.getResponseCode()));
Log.i("MSG" , conn.getResponseMessage());
} catch (Exception e) {
}
finally {
conn.disconnect();
}
}
This is how I call the POST method:
private void setTemp(String hot, String cold)
{
try {
WebAPI.setTemp(Tools.RestURLPost, hot, cold);
}
catch(IOException e) {
e.printStackTrace();
}
}
And here you can find my Node.js method which I use to test successful parsing of JSON:
router.post('/post', function(req, res, next) {
console.log(req.body);
});
Without seeing the whole code it's hard to know but you're never ending the request in Node, so use: req.send/json, otherwise the Android application will wait until the request is done, which won't happen and it will timeout.
router.post('/post', function(req, res, next) {
console.log(req.body);
res.json({ success: true });
});
I am trying to get json object as string from this url http://digitalcollections.tcd.ie/home/getMeta.php?pid=MS4418_021. It doesn't work I get an error after downloadUrl function.
java.io.IOException: unexpected end of stream on Connection{digitalcollections.tcd.ie:80, proxy=DIRECT# hostAddress=134.226.115.12 cipherSuite=none protocol=http/1.1} (recycle count=0)
Although it does work for this androidhive url http://api.androidhive.info/volley/person_object.json.
I am new to httpconnection below is my download url function. Error seems to show in this line HttpURLConnection conn = (HttpURLConnection) url.openConnection(); In the debugger after that line conn.getInputStream() shows the IO exception and the cause java.io.EOFException: \n not found: size=0 content=...
// Given a string representation of a URL, sets up a connection and gets
// an input stream.
private InputStream downloadUrl(String urlString) throws IOException {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(20000 /* milliseconds */);
conn.setConnectTimeout(30000 /* milliseconds */);
conn.setRequestMethod("GET");
//conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream stream = conn.getInputStream();
return stream;
}
Other functions.
// Uses AsyncTask to create a task away from the main UI thread. This task takes a
// URL string and uses it to create an HttpUrlConnection. Once the connection
// has been established, the AsyncTask downloads the contents of the webpage as
// an InputStream. Finally, the InputStream is converted into a string, which is
// displayed in the UI by the AsyncTask's onPostExecute method.
private class DownloadXMLTask extends AsyncTask<String, Void, List<Entry>> {
private String urlFront = "";
#Override
protected List<Entry> doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return loadJsonFromNetwork(urls[0]);
} catch (IOException e) {
Log.d(TAG, "Unable to retrieve web page. URL may be invalid.");
return null;
} catch (JSONException e) {
Log.d(TAG, "XMLPULLPARSER ERROR IN download json task function");
return null;
}
}
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(List<Entry> result) {
//post execution stuff
}
}
Loading json and parser, the parser might not work haven't tested it yet.
private List<Entry> loadJsonFromNetwork(String urlString) throws IOException, JSONException {
InputStream stream = null;
int len = 20000; //max amount of characters to display in string
List<Entry> entries = new ArrayList<Entry>();
try {
stream = downloadUrl(urlString); //IOException
String jsonStr = readit(stream,len);
if(jsonStr.equals(null)){
Log.d(TAG, "ERROR json string returned null");
return entries;
}
JSONObject jsonObj = new JSONObject(jsonStr);
//Not sure if the json parser works yet haven't got that far
// Getting JSON Array node
identifier = jsonObj.getJSONArray("identifier");
// looping through All Contacts
for (int i = 0; i < identifier.length(); i++) {
JSONObject c = identifier.getJSONObject(i);
String id = c.getString("type");
if(id.equals("DRIS_FOLDER")) {
String folder = c.getString("$");
entries.add(new Entry(null,null,null,folder));
}
}
// Makes sure that the InputStream is closed after the app is
// finished using it.
//This is where IOexception is called and stream is null
} catch (IOException e) {
Log.d(TAG, "Unable to retrieve json web page. URL may be invalid."+ e.toString());
return entries;
}
finally {
if (stream != null) {
stream.close();
}
}
return entries;
}
I am running this on a Nexus_5_API_23 emulator.
Thanks in advance.
UPDATE:
Doesn't work on Nexus_5_API_23 emulator?? Although it works on a Samsung GT-ST7500 external phone. Want it to work for the emulator.
The problem was my antivirus/firewall on my computer. It was blocking my connection and that's why it was working on a external phone and not emulator. I disabled my antivirus/firewall and it worked. There is a list of network limitations here http://developer.android.com/tools/devices/emulator.html#networkinglimitations
I just tried that URL on my device and didn't get any errors. Here is the code I used.
An Interface to get back onto the UI Thread
public interface AsyncResponse<T> {
void onResponse(T response);
}
A generic AsyncTask that returns a String - Feel free to modify this to parse your JSON and return a List.
public class WebDownloadTask extends AsyncTask<String, Void, String> {
private AsyncResponse<String> callback;
public void setCallback(AsyncResponse<String> callback) {
this.callback = callback;
}
#Override
protected String doInBackground(String... params) {
String url = params[0];
return readFromUrl(url);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (callback != null) {
callback.onResponse(s);
} else {
Log.w(WebDownloadTask.class.getSimpleName(), "The response was ignored");
}
}
private String streamToString(InputStream is) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
return sb.toString();
}
private String readFromUrl(String myWebpage) {
String response = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(myWebpage);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
response = streamToString(inputStream);
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return response;
}
}
Section of my Activity to call the AsyncTask.
String url = "http://digitalcollections.tcd.ie/home/getMeta.php?pid=MS4418_021";
WebDownloadTask task = new WebDownloadTask();
task.setCallback(new AsyncResponse<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
}
});
task.execute(url);
Make sure to use https instead of http to avoid these kind of errors on your Android Emulators.
private static final String BASE_URL = "https://content.guardianapis.com/search?";
I use AsnycTask to connect URL and parse the return xml:
class Connecting extends AsyncTask<String, String, String> {
private String URLPath = "";
private HttpURLConnection Connection;
private InputStream InputStream;
private boolean Return1 = false;
private int Return2 = -1;
public Connecting (String fn, String u) {
FileName = fn;
URLPath = u;
Connection = null;
InputStream = null;
Return1 = false;
Return2 = -1;
execute();
}
public boolean getReturn1() {
return Return1;
}
public int getReturn2() {
return Return2;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... aurl) {
try {
URL url = new URL(URLPath);
Connection = (HttpURLConnection)url.openConnection();
Connection.setConnectTimeout(10000);
Connection.setReadTimeout(10000);
Connection.setDoInput(true);
Connection.setUseCaches(false);
Connection.connect();
InputStream = Connection.getInputStream();
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String unused) {
super.onPostExecute(unused);
try {
InputStreamReader fsr = new InputStreamReader(InputStream);
BufferedReader br = new BufferedReader(fsr);
String line = "";
while((line = br.readLine()) != null) {
//parse Reture1 and Return2
}
}
catch(Exception e) {
e.printStackTrace();
}
Connection = null;
}
}
And I use below code to call it:
Connecting con = new Connecting(Name, URL);
System.out.println("Return1 " + con.getReturn1());
System.out.println("Return2 " + con.getReturn2());
It will get false and -1, which the init value.
And connect URL after print message.
I want to get the value which has connect success and parse from the xml.
How can I do it?
AsyncTask is a class that helps to run in background. You can use it if you want to access to remote server using for example HTTP connection.
In doBackground method you have to the the "heavy" task, the one that requires time and could block the UI. When you finish at the end of doBackground you have to return the value that is the result of the task.
Then in the onPostExecute you use this result to update for example the UI.
In your case it seems to me you aren't using correctly the AsyncTask. First of all you return null in doBackground and dont set return1 and return2 as you should.
And in onPostExecute you read the response while yuo should do it in doBackground.
There's another method you can override called onPreExecute that is called before doBackground method.
In my blog i've an example how to use AsyncBackground in this case and it could help you. If you like give a look here
The AsyncTask runs (as the name says) asynchronously to the main-thread.
If you want to happen something after the task is done, you have to put that code in the onPostExecute() method.
So you may put the System.out there.
I'm writing an Android app which receives data from a server. Theoretical there could not be an internet connection so I try to catch this case by catching a SocketTimeoutException to show an error message an a retry screen or something else. Unfortunately this exception won't be thrown. At least it doesn't jump into the catch clause. What am I doing wrong?
public class HttpConnector {
private String urlString;
private int connectionTimeout = 5000; //milliseconds
public HttpConnector(String urlString) {
this.urlString = urlString;
}
public String receiveData() throws PolizeiwarnungException {
URL url = null;
HttpURLConnection urlConnection = null;
StringBuffer b = new StringBuffer();
try {
url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(connectionTimeout);
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); //Here it gets stuck if there is no connection to the server
String str;
while ((str = reader.readLine()) != null) {
b.append(str + "\n");
}
}
catch (SocketTimeoutException e) {
//TODO
e.printStackTrace();
}
catch (IOException e) {
throw new PolizeiwarnungException(e);
}
finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return b.toString();
}
public void sendData(String data) {
//TODO
}
}
You need to also set the connect timeout. Please see this documentation.
Since the end point does not exist, without having set a connect time out the connection will never time out.
setConnectTimeout(int timeout) Sets the timeout value in milliseconds
for establishing the connection to the resource pointed by
this URLConnection instance.