java.net.UnknownHostException in Android when trying to reach graph.facebook.com - android

I have an android app, and I try to get information from Facebook. I use an http get request and actually worked out great in one instance (when I try to get a user mutual friends list).
However, I have attempted to get the user events, and for some reason I get this exception. The funny thing is that the URL works great (tested it in a browser while debugging) and as mentioned - I use the same method in another place in my code to get something and it works. I'm completely losing it trying to figure out what's wrong!
Here's the code:
String accessToken = Session.getActiveSession().getAccessToken();
String query = "https://graph.facebook.com/me/events/attending?fields=id,name,location,venue,start_time,end_time,privacy&access_token=" + accessToken;
HttpGet get = new HttpGet(query);
HttpClient client = new DefaultHttpClient();
try {
HttpResponse response = client.execute(get);
String result = EntityUtils.toString(response.getEntity());
JSONObject eventsJsonObj = new JSONObject(result);
JSONArray eventsArray = eventsJsonObj.getJSONArray("data");
for (int i=0; i < eventsArray.length(); i++) {
// do something with event
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
EDIT: here's the stack trace and the url as taken in debug and checked in browser (replacing of course the access token with [access_token]). btw, you can try the url yourself with an access token from the graph api explorer
URL: https://graph.facebook.com/me/events/attending?fields=id,name,location,venue,start_time,end_time,privacy&access_token=[access_token]
06-17 15:07:17.684: W/System.err(22733): java.net.UnknownHostException
06-17 15:07:17.684: W/System.err(22733): at org.apache.http.impl.conn.DefaultClientConnectionOperator.getAllByName(DefaultClientConnectionOperator.java:272)
06-17 15:07:17.684: W/System.err(22733): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:153)
06-17 15:07:17.684: W/System.err(22733): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:167)
06-17 15:07:17.689: W/System.err(22733): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:125)
06-17 15:07:17.689: W/System.err(22733): at org.apache.http.impl.client.DefaultRequestDirector.executeOriginal(DefaultRequestDirector.java:1171)
06-17 15:07:17.689: W/System.err(22733): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:637)
06-17 15:07:17.689: W/System.err(22733): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
06-17 15:07:17.689: W/System.err(22733): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
06-17 15:07:17.694: W/System.err(22733): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
06-17 15:07:17.694: W/System.err(22733): at

After a lot of aggression towards Eclipse, I finally figured out the dumb (yet reasonable) mistake I made.
I called the request on the main thread, which is something everybody knows not to do. So that was the issue… if anyone ever runs into.
Facebook takes get requests.

Related

NullPointerException only when on Google Play Store?

I recently uploaded an update of my app to Google Play. When trying it out, I get an error when clicking on a manually added banner (e.g. not AdMob or anything like that). The click is setting of an AsyncTask that sends data to a php-script using POST. I use ProGuard so when I send the error report to myself I am only able to see the method in which the error is caused: doInBackground. I am also able to see that it is a NullPointerException. The strange thing is, when I run the app on my device from my computer using Eclipse, the error doesn't occur, so I can't really find what line is causing the NullPointerException. It has worked perfectly in previous versions of my app, and I haven't made any changes to this code. And when I look through the method doInBackground, I can't find any place where a NullPointerException might occur.
Here is the error message from my developers console, this is proguarded though:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:278)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.NullPointerException
at se.nollekollen.main.d.a(Unknown Source)
at se.nollekollen.main.d.doInBackground(Unknown Source)
at android.os.AsyncTask$2.call(AsyncTask.java:264)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
... 5 more
And here is my doInBackground:
#Override
protected String doInBackground(String... arg0) {
String url_stats = "http://xxxxx.xx/statistik/sendStatistics_click.php";
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("activity", getClass().getEnclosingClass().getName().substring(20)));
params.add(new BasicNameValuePair("section", SECTION));
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_stats);
try {
httpPost.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
try {
httpClient.execute(httpPost);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
The only thing that could be null here is actually "SECTION", but that wouldn't cause a NullPointerException since the value can be null when creating a new BasicNameValuePair(key, value).
Can anyone find what could cause the NullPointerException? And how is it possible that this ONLY occurs when the app is downloaded from Google Play, and not when run from the computer?

about android sending get request

Here I have a problem with getting request in Android.
I have run server program using webapp2 on my PC and I succeeded in sending request from itself to the server program.
However, when I tried to send request from my phone, it seems the program always jump the catch(Exception e) part. The three Log.e() works fine since I could see all of them in the log records. Can anyone tell me what might go wrong here? Is it the fire wall that my PC used to block the request? Thanks in advance.
PS: the variable resultString is the result I get from voice recognition.
try{
StringBuilder buf = new StringBuilder("http://192.168.1.100:9080/");
buf.append("?");
buf.append("content1="+URLEncoder.encode(resultString,"UTF-8"));
//buf.append(resultString);
//Toast.makeText(MainActivity.this, buf, Toast.LENGTH_SHORT).show();
URL url = new URL(buf.toString());
Log.e("check1","url_transformation works ok");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
Log.e("check2","open connection works ok");
conn.setRequestMethod("GET");
Log.e("check3","set get works ok");
if(conn.getResponseCode()==200){
Log.e("check4","get works");
Toast.makeText(MainActivity.this, "GET works", Toast.LENGTH_SHORT).show();
}
else
{
Log.e("check5","get fails");
Toast.makeText(MainActivity.this, "GET fails", Toast.LENGTH_SHORT).show();
}
}
catch(Exception e){
Toast.makeText(MainActivity.this, "other problems occur", Toast.LENGTH_SHORT).show();
}
03-05 20:47:19.486: W/System.err(16066): android.os.NetworkOnMainThreadException
03-05 20:47:19.486: W/System.err(16066): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1178)
03-05 20:47:19.486: W/System.err(16066): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
03-05 20:47:19.486: W/System.err(16066): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
03-05 20:47:19.486: W/System.err(16066): at libcore.io.IoBridge.connect(IoBridge.java:112)
03-05 20:47:19.486: W/System.err(16066): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
03-05 20:47:19.486: W/System.err(16066): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
03-05 20:47:19.486: W/System.err(16066): at java.net.Socket.connect(Socket.java:872)
03-05 20:47:19.486: W/System.err(16066): at libcore.net.http.HttpConnection.(HttpConnection.java:77)
I think the exception log is as described as above. So what's wrong here?
I have tried AsyncTask as some of you suggested.
The code is as belowed:
private class HttpGetTask extends AsyncTask<Void , Void, String> {
private String URL = "http://192.168.1.100:9080/" + "?" +"content1="+resultString;
//buf.append("content1="+URLEncoder.encode(resultString,"UTF-8"));
AndroidHttpClient mClient = AndroidHttpClient.newInstance("");
//Log.e("check", "succeed");
#Override
protected String doInBackground(Void... param) {
HttpGet request = new HttpGet(URL);
//Log.e("check1","succeed");
Log.e("url",URL);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
try {
Log.e("check3","succeed");
return mClient.execute(request, responseHandler);
} catch (ClientProtocolException exception) {
exception.printStackTrace();
Log.e("check4","succeed");
} catch (IOException exception) {
exception.printStackTrace();
Log.e("check5","succeed");
}
Log.e("check6","succeed");//to this point
return null;
}
#Override
protected void onPostExecute(String result) {
if (null != mClient)
mClient.close();
//Log.e("check6","succeed");
mTextView.setText(result);
}
}
03-06 14:57:07.117: W/System.err(12451): org.apache.http.conn.ConnectTimeoutException: Connect to /192.168.1.100:9080 timed out
03-06 14:57:07.137: W/System.err(12451): at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121)
03-06 14:57:07.137: W/System.err(12451): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
the Log shows that there is an IOException in my codes and the value of mClient will eventually be null.I have looked online for the same situation and it seems this occurs when data takes too much time to respond that is requested. And many of the answers suggested I should reset Timeout and allow more time for the request to be sent. But I don't really understand where to put the reset codes in my situation. Can anyone help with this? Thanks.
NetworkOnMainThreadException is thrown when you try to perform network operations on the main/UI thread. This is not allowed in Android. Instead, you need to perform network operations in a background thread. You can do this using an AsyncTask.
You can put this on onCreate(), but the best option is to use AsyncTask.
StrictMode.ThreadPolicy threadPolicy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(threadPolicy);

HttpHostConnectException: Connection refused Android

I am trying to connect via HttpPost and send a username and password to a website and then receive a string from that website. I have tried various methods that have worked for me in the past but now when I send the username and password identifiers the app times out for as long as 4 minutes and then spits out the following exception:
07-16 16:32:32.897: W/System.err(632): Unable to connect to the server
07-16 16:32:32.907: W/System.err(632): org.apache.http.conn.HttpHostConnectException: Connection to http://devdashboard.company refused
07-16 16:32:32.917: W/System.err(632): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:183)
07-16 16:32:32.917: W/System.err(632): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
07-16 16:32:32.917: W/System.err(632): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
07-16 16:32:32.917: W/System.err(632): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
07-16 16:32:32.917: W/System.err(632): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
07-16 16:32:32.917: W/System.err(632): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
07-16 16:32:32.927: W/System.err(632): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
07-16 16:32:32.927: W/System.err(632): at company.android.dashboard.app.HttpHelperAndroid.sendToHttp(HttpHelperAndroid.java:66)
07-16 16:32:32.927: W/System.err(632): at company.android.dashboard.app.DashboardAppActivity.goToDashboard(DashboardAppActivity.java:62)
07-16 16:32:32.927: W/System.err(632): at java.lang.reflect.Method.invokeNative(Native Method)
07-16 16:32:32.937: W/System.err(632): at java.lang.reflect.Method.invoke(Method.java:511)
07-16 16:32:32.937: W/System.err(632): at android.view.View$1.onClick(View.java:3039)
07-16 16:32:32.947: W/System.err(632): at android.view.View.performClick(View.java:3511)
07-16 16:32:32.947: W/System.err(632): at android.view.View$PerformClick.run(View.java:14105)
07-16 16:32:32.947: W/System.err(632): at android.os.Handler.handleCallback(Handler.java:605)
07-16 16:32:32.957: W/System.err(632): at android.os.Handler.dispatchMessage(Handler.java:92)
07-16 16:32:32.957: W/System.err(632): at android.os.Looper.loop(Looper.java:137)
07-16 16:32:32.967: W/System.err(632): at android.app.ActivityThread.main(ActivityThread.java:4424)
07-16 16:32:32.977: W/System.err(632): at java.lang.reflect.Method.invokeNative(Native Method)
07-16 16:32:32.977: W/System.err(632): at java.lang.reflect.Method.invoke(Method.java:511)
07-16 16:32:32.977: W/System.err(632): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
07-16 16:32:32.987: W/System.err(632): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
07-16 16:32:32.987: W/System.err(632): at dalvik.system.NativeStart.main(Native Method)
07-16 16:32:32.987: W/System.err(632): Caused by: java.net.ConnectException: failed to connect to /50.19.240.232 (port 80): connect failed: ETIMEDOUT (Connection timed out)
07-16 16:32:32.997: W/System.err(632): at libcore.io.IoBridge.connect(IoBridge.java:114)
07-16 16:32:32.997: W/System.err(632): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
07-16 16:32:32.997: W/System.err(632): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
07-16 16:32:33.007: W/System.err(632): at java.net.Socket.connect(Socket.java:842)
07-16 16:32:33.007: W/System.err(632): at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:119)
07-16 16:32:33.017: W/System.err(632): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144)
07-16 16:32:33.017: W/System.err(632): ... 22 more
07-16 16:32:33.027: W/System.err(632): Caused by: libcore.io.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
07-16 16:32:33.047: W/System.err(632): at libcore.io.Posix.connect(Native Method)
07-16 16:32:33.047: W/System.err(632): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:85)
07-16 16:32:33.047: W/System.err(632): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
07-16 16:32:33.057: W/System.err(632): at libcore.io.IoBridge.connect(IoBridge.java:112)
07-1
6 16:32:33.057: W/System.err(632): ... 27 more
Internet permission IS enabled in my XML manifest file
My current implementation goes like this:
String LOGIN = "email#gmail.com";
String PASSWORD ="password1";
//JSONObject to send the username and pw
JSONObject json = new JSONObject();
//put the path in the JSONArray object
JSONArray vect = new JSONArray();
vect.put("company Android Library");
vect.put("Rocket Ship");
int duration = 50;
try {
json.put("email", LOGIN);
json.put("password", PASSWORD);
json.put("json", "true");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d(TAG, "ABOUT TO SEND:" + json.toString());
JSONObject inJson = HttpHelperAndroid.sendToHttp(json, "http://devdashboard.company/login");
if(inJson != null)
{
Log.d(TAG, "RECIEVED the JSON:" + inJson.toString());
}
else
Log.d(TAG, "THE RESPONSE WAS NULL");
}
And the HttpHelperAndroid class looks like so:
public class HttpHelperAndroid
{
private static final String TAG = "HttpHelperAndroid";//TAG for the LogCat(debugging)
private static boolean responseSuccessful = true;
/**
* sends the JSONObject parameter to the desired URL parameter and gets the response
*
* #param url the URL to which the JSONObject should be sent
* #param jsonObjOut the JSONObject that is to be sent
* #return the response from the server as a JSONObject
*/
public static JSONObject sendToHttp(JSONObject jsonObjOut, String url) {
responseSuccessful = true;
try
{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpRequest = new HttpPost(url);
//convert the JSONObject to a string
StringEntity se;
//set our StringEntity to the JSONObject as a string
se = new StringEntity(jsonObjOut.toString());
// Set HTTP params
httpRequest.setEntity(se);
httpRequest.setHeader("Accept", "application/json");
httpRequest.setHeader("Content-type", "application/json");
httpRequest.setHeader("Accept-Encoding", "gzip"); //for gzip compression
//get the current time
long oldTime = System.currentTimeMillis();
HttpResponse response = null;
try
{
//execute the http request and get the response
response = (HttpResponse) httpClient.execute(httpRequest);
}
catch(HttpHostConnectException e)
{
System.err.println("Unable to connect to the server");
e.printStackTrace();
responseSuccessful = false;
}
//only continue executing if we got a response from the server
if(responseSuccessful)
{
//print how long the response took to the LogCat if it's on
Log.i(TAG, "HTTPResponse received in [" + (System.currentTimeMillis()-oldTime) + "ms]");
// Get hold of the response entity (-> the data):
HttpEntity entity = response.getEntity();
if (entity != null) {
// Read the content stream
InputStream in = entity.getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
in = new GZIPInputStream(in);
}
// convert content stream to a String
String resultString= streamToString(in);
//close the stream
in.close();
// convert the String into a JSONObject
JSONObject jsonObjRecv = new JSONObject(resultString);
//take a peak at the JSONObject we got back if the LogCat is on
Log.i(TAG,"<JSONObject>\n"+jsonObjRecv.toString()+"\n</JSONObject>");
//return the JSONObject we got back from the server
return jsonObjRecv;
}
}
}
//catch any exception that was thrown
catch (Exception e)
{
//Print the exception
e.printStackTrace();
}
return null;
}
private static String streamToString(InputStream is)
{
//create a new BufferedReader for the input stream
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
//create a new StringBuilder to append the lines
StringBuilder sb = new StringBuilder();
//initialize an empty string
String line = null;
try
{
//iterate as long as there is still lines to be read
while ((line = reader.readLine()) != null)
{
//append the line and a newline character to our StringBuilder
sb.append(line + "\n");
}
}
//catch an IOException and print it
catch (IOException e) {
e.printStackTrace();
}
//close the stream when we're done
finally
{
try
{
is.close();
}
//catch and print an exception if it's thrown
catch (IOException e)
{
e.printStackTrace();
}
}
//return the stream converted to a string
return sb.toString();
}
}
And here is my XML just for kicks:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="company.android.dashboard.app"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk android:minSdkVersion="7" />
<application
android:icon="#drawable/company_android_ico"
android:label="#string/app_name" >
<activity
android:name=".DashboardAppActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I have used the HttpHelper class in past projects and it has worked for me, in addition I tried to implement this using nameValuePairs:
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("email", "email#gmail.com"));
nameValuePairs.add(new BasicNameValuePair("password", "password1"));
nameValuePairs.add(new BasicNameValuePair("json", "true"));
try {
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
And this yielded the same result.
Could this somehow be a certificate thing? or perhaps something to do with a corrupt XML file( I tried remaking the project and the xml file) Android HTTP Connection refused
Or maybe some sort of Android hosts file issue?
I'm open to any suggestions!
I have examined this from a lot of angles and I'm happy to provide any other information that would be helpful! I really appreciate your time!
NOTE: The url is a dummy url, and not the actual one I am connecting to, for security reasons. I am able to curl the actual website from the command line with the parameters and it works and I am also able to login normally from the web browser.
EDIT I have identified the problem! But not the solution unfortunately. So the issue is that I am using a dev server url that doesn't have a domain entry on the global DNS server. So to fix this I somehow need to edit the hosts file on my Android device/in the emulator...does anyone know how this can be done legitimately?
I have identified the problem! So the issue is that I am using a dev server url that doesn't have a domain entry on the global DNS server.
So there are two possible solutions to this issue:
1) Editing the hosts file on the Android device (requires rooting your phone): How to change the hosts file on android
2) Getting the server registered on the global DNS server.
(also hard to do if you're not responsible for the url)
Anyways I hope this helps someone else too!
Please follow these solution may be among these one solve your issue.
1> check your manifest file internet permission there or not.
2> check your url with browser by rest client and pass the appropriate request.
3> open the url in mobile like:- http://your ip address/port that's it just for checking do you have a permission or not to open this url in mobile.
There are a few possibilities
1) the url is incorrect "http://devdashboard.company/login" is not right. At least check in browser.
ping the host as well.
2) This should be an https connection instead.
3) there is some certification required.
4) You are missing a port number. or domain has not been setup correctly.
perhaps port 80 the default is incorrect?
5) the call should not be a post.
In general you are either responsible for the server or you are not. It appears that it is some elses responsibility, and you should ask them what the correct url and parameters are. So its probably no ones fault, but you need to ask them about the connection to verify.
The other thing you can do is to try and see what the url looks like in an application that is succesfully connectiing. take a look that this.
The problem is in wifi sleeping.
Please use
WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL , "MyWifiLock");
wifiLock.acquire();
and permission:
uses-permission android:name="android.permission.WAKE_LOCK";
This post is old, but it is the first result when googling this error. I encountered the same exception, and everything was completely correct in my code. I commented out the line containing the INTERNET permission in my AndroidManifest.xml, ran the app, clicked/tapped my button to send the HTTP request and get the exception, closed the app, went back to the manifest, uncommented the permission line, ran the app again, and the exception was resolved!
This kind of bugs in 2015 (and in "advanced" tools like the latest compile tools for Android API 21, and Intellij IDEA 14) drives me mad! You are approaching your deadline, and this sort of bugs completely disrupts your work!

Using AndroidHttpClient will not work

I am trying to use AndroidHttpClient to download a CSV file. For some reason it fails in the line "HttpResponse response httpClient.execute(httpGet, localContext); and simply goes to "finally".
I've checked the URL in my browser - it is working fine.
I get no information from HttpResponse response - it simply like skips it.
I don't get why. Any ideas?
Thanks
D
private ArrayList<String> retrieveStockFinParamsFromYahooApiUri(String yahooApiCall)
{
ArrayList<String> stockFinParamsFromYahooApiUriRows = new ArrayList<String>();
String resultLine = "";
BufferedReader reader = null;
AndroidHttpClient httpClient = AndroidHttpClient.newInstance("yahooGetStockParams");
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(yahooApiCall);
try
{
HttpResponse response = httpClient.execute(httpGet, localContext);
reader = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
while ((resultLine = reader.readLine()) != null)
{
stockFinParamsFromYahooApiUriRows.add(resultLine);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (reader != null)
{
try
{
reader.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
return stockFinParamsFromYahooApiUriRows;
}
FURTHER INVESTIGATION (05.22.2012):
#Snicolas - thank you for your comments. After I read your comments I thought the problem might originate from the fact that I used the emulator and not my actual device to debug this. I thought the emulator might suffer some connection problems. When I tested it on my device - I noticed the problem still occurred - so this was NOT the problem.
So I change my code to catch (Throwable e) as you advised and got the following stack snapshot:
05-22 18:17:41.457: W/System.err(24552): android.os.NetworkOnMainThreadException
05-22 18:17:41.461: W/System.err(24552): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
05-22 18:17:41.461: W/System.err(24552): at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
05-22 18:17:41.461: W/System.err(24552): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
05-22 18:17:41.465: W/System.err(24552): at java.net.InetAddress.getAllByName(InetAddress.java:220)
05-22 18:17:41.465: W/System.err(24552): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
05-22 18:17:41.465: W/System.err(24552): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
05-22 18:17:41.468: W/System.err(24552): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
05-22 18:17:41.468: W/System.err(24552): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
05-22 18:17:41.468: W/System.err(24552): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
05-22 18:17:41.472: W/System.err(24552): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
05-22 18:17:41.472: W/System.err(24552): at android.net.http.AndroidHttpClient.execute(AndroidHttpClient.java:257)
05-22 18:17:41.472: W/System.err(24552): at com.bewildering.app.StournamentDbAdapter$YahooStocksParams.retrieveStockFinParamsFromYahooApiUri(StournamentDbAdapter.java:1536)
05-22 18:17:41.476: W/System.err(24552): at com.bewildering.app.StournamentDbAdapter$YahooStocksParams.run(StournamentDbAdapter.java:1709)
05-22 18:17:41.476: W/System.err(24552): at com.bewildering.app.StournamentActivity.onCreate(StournamentActivity.java:65)
05-22 18:17:41.476: W/System.err(24552): at android.app.Activity.performCreate(Activity.java:4465)
05-22 18:17:41.476: W/System.err(24552): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
05-22 18:17:41.480: W/System.err(24552): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
05-22 18:17:41.480: W/System.err(24552): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
05-22 18:17:41.480: W/System.err(24552): at android.app.ActivityThread.access$600(ActivityThread.java:123)
05-22 18:17:41.484: W/System.err(24552): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
05-22 18:17:41.484: W/System.err(24552): at android.os.Handler.dispatchMessage(Handler.java:99)
05-22 18:17:41.484: W/System.err(24552): at android.os.Looper.loop(Looper.java:137)
05-22 18:17:41.484: W/System.err(24552): at android.app.ActivityThread.main(ActivityThread.java:4424)
05-22 18:17:41.488: W/System.err(24552): at java.lang.reflect.Method.invokeNative(Native Method)
05-22 18:17:41.488: W/System.err(24552): at java.lang.reflect.Method.invoke(Method.java:511)
05-22 18:17:41.488: W/System.err(24552): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-22 18:17:41.492: W/System.err(24552): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-22 18:17:41.492: W/System.err(24552): at dalvik.system.NativeStart.main(Native Method)
While looking for android.os.NetworkOnMainThreadExceptionI found the documentation which states that this is: The exception that is thrown when an application attempts to perform a networking operation on its main thread.
From that I conclude that I should put my call into an AsyncTask.
Can anyone please confirm that I understand this correctly - or am I missing something here? Strange that I hat to catch (Throwable e) in order to get to the bottom of this.
FURTHER INVESTIGATION (05.22.2012):
I can now confirm that this issue comes due to the fact that The exception... is thrown when an application attempts to perform a networking operation on its main thread. As I read this started with honeycomb.
Ths issue now: I get a 301 response from Yahoo (Moved Permanently). This is strange because when I cut paste the URL into the browser it works.
Any idea why this should work in the browser but not in the application? I must mention that this HTTP request receives a CSV file as a response. Could this be an issue?
FURTHER INVESTIGATION (05.23.2012):
For some reason when using (in my code) the Yahoo URI http://finance.yahoo.com/d/quotes.csv?s= the response is a 301 (Moved Permanently). When using http://download.finance.yahoo.com/d/quotes.csv?s= instead the response is 200 (OK). Even that both work fine in the browser. I was lucky enough to find this web page that gave me some clues regarding which URIs Yahoo reacts to. Now I can see the "reader" gets the data and everything is ALMOST fine. I still get some strange exception (still trying to figure it out): after reading all the lines in the response I catch a Throwable (I left it from my previous experiments) and later on in the stack I thus get 05-23 08:52:41.258: W/dalvikvm(933): threadid=11: thread exiting with uncaught exception (group=0x40a721f8) and something about an uncaught exception in doInBackground(Void... params). Still investigating...
Just solved this issue - it was just a mistake in calling the Yahoo API. Had to add &e=.csv to the end of the URI for it to work. Just like that: http://download.finance.yahoo.com/d/quotes.csv?s=KDHIX&f=sl1d1t1c1ohgv&e=.csv
FINAL CODE
private ArrayList<String> retrieveStockFinParamsFromYahooApiUri(String yahooApiCall)
{
ArrayList<String> stockFinParamsFromYahooApiUriRows = new ArrayList<String>();
String resultLine = "";
BufferedReader reader = null;
AndroidHttpClient httpClient = AndroidHttpClient.newInstance("yahooGetStockParams");
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(yahooApiCall);
try
{
HttpResponse response = httpClient.execute(httpGet, localContext);
reader = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
while ((resultLine = reader.readLine()) != null)
{
stockFinParamsFromYahooApiUriRows.add(resultLine);
}
if(response != null)
{
try
{
response.getEntity().consumeContent();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if(httpClient != null)
{
httpClient.close();
}
if (reader != null)
{
try
{
reader.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
return stockFinParamsFromYahooApiUriRows;
}
Chances are that you get an Exception in execute that is not an IOException. Then, your catch block never get executed and your finally block is executed before the method throws an exepected exception to the caller of retrieveStockFinParamsFromYahooApiUri.
You have at least 2 options :
don't catch an IOException but a prent class. Try Throwable, print the stack trace and see what happens. Then you can later add other catch blocks to handle the case. (Catching Throwables is a bad programming practice, but you can use temporarily).
place the invocation of retrieveStockFinParamsFromYahooApiUri in a try catch block using the same mechanism as above to determine which exception classes to expect and act accordingly.
But you need to refine your understanding of the problem, catch everything possible, write the stack trace and check the logcat.
Here are some other advices :
You need to check the result code of the request before reading its content.
You could use Apache IOUtils to copy the content of the response input stream and cache it to a file.
You could enable gzipping of the request and the response.
You also need to close properly the HttpConnection in the finally block, you can consume the entity of the response to achieve this.

UnknownHostException when sending HTTPS/HTTP POST from Android Device

I'm trying to create an HTTP POST to Google servers to obtain the ClientLogin Auth (as described here). The source code for the post is not a real mystery and I found it here. (I'm sure my post works because using CURL I obtain the Auth)
The method is very simple and I've modified the values accordingly, however, I'm getting the following exception when I execute the following line:
HttpResponse response = client.execute(post);
06-17 13:44:05.645: WARN/System.err(768): java.net.UnknownHostException: www.google.com
06-17 13:44:05.645: WARN/System.err(768): at java.net.InetAddress.lookupHostByName(InetAddress.java:506)
06-17 13:44:05.645: WARN/System.err(768): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:294)
06-17 13:44:05.645: WARN/System.err(768): at java.net.InetAddress.getAllByName(InetAddress.java:256)
06-17 13:44:05.645: WARN/System.err(768): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:136)
06-17 13:44:05.645: WARN/System.err(768): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
06-17 13:44:05.645: WARN/System.err(768): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
06-17 13:44:05.645: WARN/System.err(768): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
06-17 13:44:05.645: WARN/System.err(768): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
06-17 13:44:05.645: WARN/System.err(768): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
06-17 13:44:05.645: WARN/System.err(768): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
etc.
etc.
etc…
(irrelevant log omitted).
After trying various combinations of code (found on google and here), different URLs too (with or without HTTPS), regular HTTP too, etc. I've decided to try the following:
try {
InetAddress address = InetAddress.getByName("http://www.google.com");
} catch (UnknownHostException e) {
e.printStackTrace();
}
and I get the same error: (trimmed the irrelevant parts too)
06-17 13:53:07.445: WARN/System.err(820): java.net.UnknownHostException: http://www.google.com
06-17 13:53:07.449: WARN/System.err(820): at java.net.InetAddress.lookupHostByName(InetAddress.java:506)
06-17 13:53:07.449: WARN/System.err(820): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:294)
06-17 13:53:07.449: WARN/System.err(820): at java.net.InetAddress.getByName(InetAddress.java:325)
Now I've sure restarted Eclipse, The Phone, I've even forgotten the Wi-Fi and re-created it. I'm using a STATIC IP address on the phone with either Google's DNS or OpenDNS (i've swapped them to try). Internet on the phone works, other applications work.
I do have
<uses-permission android:name="android.permission.INTERNET" />
on my Manifest in the correct spot (inside Application), in fact I also have "android.permission.ACCESS_FINE_LOCATION" but that doesn't change anything.
Device
It's a fresh Nexus-S (unlocked) with Android 2.3.4.
Code that Fails
This is the method in question: (see line HttpResponse response = client.execute(post);)
Please note that I've removed the "real values" but rest assured the correct values are in the original code.
public void getAuthentification(View view) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(
"https://www.google.com/accounts/ClientLogin");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("Email", prefs.getString(
"user", "undefined")));
nameValuePairs.add(new BasicNameValuePair("Passwd", prefs
.getString("password", "undefined")));
nameValuePairs.add(new BasicNameValuePair("accountType", "GOOGLE"));
nameValuePairs.add(new BasicNameValuePair("source",
"Google-cURL-Example"));
nameValuePairs.add(new BasicNameValuePair("service", "ac2dm"));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
Log.e("HttpResponse", line);
if (line.startsWith("Auth=")) {
Editor edit = prefManager.edit();
edit.putString(AUTH, line.substring(5));
edit.commit();
String s = prefManager.getString(AUTH, "n/a");
Toast.makeText(this, s, Toast.LENGTH_LONG).show();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
What am I missing?
Ok, after reading this answer and in contrary to what I've read in other google results, the…
<uses-permission android:name="android.permission.INTERNET" />
…must be outside the application.
I have it:
<!-- General Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Now it works.
Do you try it on Device? Sometimes what happens is that emulator fails to resolve DNS and gives an error message.

Categories

Resources