Android-- HttpClient runtime exception while executing a HttpGet request - android

I was building an enquiry to google's direction service, but the execute method crashed halfway, Here's the code
Uri.Builder b = Uri.parse("http://maps.googleapis.com/maps/api/directions/json").buildUpon();
b.appendQueryParameter("origin", "The University of Hong KOng");
b.appendQueryParameter("destination", "Lee Hysan Hall");
b.appendQueryParameter("sensor", "false");
b.appendQueryParameter("language", "en_US");
String finalstr = b.build().toString();
URI googledirectionservice = new URI(finalstr);
HttpGet mRequest = new HttpGet(googledirectionservice);
HttpClient mClient = new DefaultHttpClient();
response = mClient.execute(mRequest);
The url constructed is fine when I access it from my browser, but it wouldn't work accessed from the HttpClient.You can double check with
http://maps.googleapis.com/maps/api/directions/json?origin=The%20University%20of%20Hong%20KOng&destination=Lee%20Hysan%20Hall&sensor=false&language=en_US
What would be the reason? Besides, how can I make the debugging information more informative? The current ones in logcat showed nothing more than
threadid=... thread exiting with uncaught exception

try turning on logging in your client. instructions sample here or here
Access to the WIRE logs and to the HEADER logs is a must in developing networked apps. So, depending on the client you are using for your http implementation, you should google until you know how to expose the appropriate logs. If you have the logs for WIRE and for HEADERS, answers to questions like you post will be pretty much self-evident in the log details.
In my case, i just keep available an extra jar file built with my http implementation with the logs activated and when i need to debug the network, i just rebuild my app with that jar. It all depends on which http lib you have chosen.
list of libs:
loopj
volley

Related

Android cannot reach Restlet service running on same network

I am testing an Android app which is connected to my local router. On the same WiFi network are also running some Java web services using Restlets. I verified that the Android app can hit the service filter and even receive a response from the service filter. However, it cannot seem to hit the Restlet service in question.
The full URL to the service is:
http://192.168.0.148:8080/MyApp/service/login
where 192.168.0.148 is the local IP address of the computer running the Restlet web services.
I have the service mapped in my Restlet Application class as follows:
router.attach("/login", LoginResource.class);
My web.xml file has the appropriate mappings to route anything with the pattern /service/ to the Restlet servlet.
I can successfully hit this service when testing from SOAP UI using precisely the same URL I gave above. In fact, all web services have been tested end-to-end using SOAP UI and are completely functional.
For some reason, the Android app can hit the service filter, when but when it reaches:
chain.doFilter(request, response);
the request ends up lost in space, and nothing gets returned.
I suspect that this is largely a Reslets configuration problem, though I don't know exactly what is happening here.
I got virtually no feedback, either from the SO community or from Restlets, which actually makes sense given that everything I reported in the question is correct. I decided to attach the Restlet sources to my IntelliJ IDE, and step through the code. I had seen that the Tomcat logs contained a response code of 415, and by inspecting the actual exception inside Restlets, I saw an error stating that the media type I posted was unexpected. Upon seeing this, I immediately knew what I had done wrong, which was:
not sending proper JSON to the login service
not declaring the content type to be JSON in the header of the POSt
and using Restlet services all of which expect JSON
For anyone who faces as similar problem using Restlets with JSON, the following Android code got everything working with no issues:
String endpoint = "http://192.168.0.148:8080/MyApp/service/login";
URL obj = new URL(endpoint);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setDoInput(true);
con.setDoOutput(true);
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
JSONObject json = new JSONObject();
json.put("username", username);
json.put("password", password);
// etc.

Android - Basic Authenticated HTTP Request

So basically i need my android app to connect to a web service using a url as such
"http://username:password#0.0.0.0" aka basic authentication.
obviously the username and password are checked by the web app before allowing access and otherwise doesn't allow the request.
my issue is that all the methods i try always say unauthorised (response code 401) regardless of what combination of classes and methods ive used to try and connect to the the url.
The web app in question is designed to return things only is un/pw clears otherwise it returns nothing, the web app and un/pw etc have all be checked and cleared.
so does anyone no the correct way to send a request to a url like that and have it work correctly?
android api8 btw
UPDATE
Turns out my issue is due to the web app using NTLM windows authentication which is not supported directly by androids/apache http library, investigating appropriate workarounds now
Here's some code form a really old project of mine. I used basic auth for some web service, and this worked at the time. I'm not sure if there are updated api's since then (this was Android 1.6), but it should still work.
HttpGet request = new HttpGet();
request.setURI(new URI(url));
UsernamePasswordCredentials credentials =
new UsernamePasswordCredentials(authUser, authPass);
BasicScheme scheme = new BasicScheme();
Header authorizationHeader = scheme.authenticate(credentials, request);
request.addHeader(authorizationHeader);
Basically, Basic HTTP auth is a simple hash of the user and password. The browser allows you to stuff these values in the url, but it actually does the work of adding the basic auth header to your request.

Authentication Error when using HttpPost with DefaultHttpClient on Android

I'm running into a strange problem using HttpClient. I am using a DefaultHttpClient() with HttpPost. I was using HttpGet with 100% success but now trying to switch to HttpPost as the REST API I'm using wants POST parameters rather than GET. (Only for some API calls though so I know that the GET calls were working fine so it's not a fault of the API).
Also, I tried using HttpPost on a simple php script I wrote that looks for a POST parameter 'var' and echoes it to screen, passing this parameters as follows worked fine:
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
postMethod = new HttpPost("http://www.examplewebsite.com");
nameValuePairs.add(new BasicNameValuePair("var", "lol"));
try {
postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs));
response = httpClient.execute(postMethod, responseHandler);
Log.i("RESTMethod", response);
...
The problem is that when I tried and do the same call to the API (but with the params changed to the API params obviously) I get the following error:
Authentication error: Unable to respond to any of these challenges: {}
The page I am requesting is an HTTPS page, could this be the problem?
But doing the same type of POST request to a raw HTTP page on the API gives the same error, unless I comment out the StringEntity part and then it runs (but returns xml and I want to pass a parameter to request the data in JSON).
This seems like a really strange problem (the non-https part) but couldn't really find any help on this problem so sorry if the answer is out there.
Any ideas?
Thanks in advance,
Infinitifzz
EDIT: Okay I'm getting nowhere so I thought if I directed you to the API it might shed some light, it's the 8Tracks API and as you can see you need to pass a dev key (api_key) for all requests and I the part I'm stuck on is using https to log a user in with: http://www.8tracks.com/sessions.xml" part.
Hope this helps somehow because I am at a dead end.
Thanks,
Infinitifizz
Authentication error: Unable to
respond to any of these challenges: {}
This error message means that the server responded with 401 (Unauthorized) status code but failed to provide a single auth challenge (WWW-Authenticate header) thus making it impossible for HttpClient to automatically recover from the authentication failure.
Most likely application expects some soft of credentials in the HTML form enclosed in the HTTP POST request.
Don't you have to declare the port and protocol? I'm just swagging this code so please don't be upset if it doesn't immediatley compile correctly. Also, I usually supply a UsernamePasswordCredentials to my setCredentials() but I imagine it's the same.
HttpHost host = new HttpHost("www.foo.com", 443, "https");
// assemble your GET or POST
client.getCredentialsProvider().setCredentials(new AuthScope(host.getHostName(), host.getPort()));
HttpResponse response = client.execute(host, [HttpPost or HttpGet]);
More info about setCredentials here.
Here's how I ended up with similar problem:
DefaultHttpClient client = new DefaultHttpClient();
client.getCredentialsProvider().setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(username, password));
Thanks to Ryan for right direction.
Not specifying a Callback URL for my Twitter App resulted in the same error for me:
Authentication error: Unable to respond to any of these challenges: {oauth=WWW-Authenticate: OAuth realm="https://api.twitter.com"}
Setting a callback URL on Twitter fixed the problem

Android app accesses web service

I need to create an Android application, I'm not sure which is a better way of doing this by better I mean should I use the WebView or create an application .
I need to implement the existing application which is a ASP.NET application which mainly consists of a login screen, once the user logs in he will see a list a items in probably a gridview based on the selection from the gridview. He then will be shown more detailed info about the selected item.
The above is a web application I need to implement this as a app on Android phone.
Also there will be a need to use the GPS where based on the GPS values the department will be selected and also use the camera to take a picture and save it on to the server .
A solution which I was thinking of was to expose .NET web services and then access it in the android phone!
But I am very new to Android development and really do not how to go about this. Is there any better solution?
Can anyone help me as to how do I go about this ?
Pros:
Android App may work faster then web applications (but still depends on web page complexity)
By the help of this community and android developer site you can complete your app within a 2-3 weeks.
As you stated picture capture/upload and GPS etc are advantages of the smart phone app.
Cons:
Later, you may need iPhone, Blackberry apps!
Instead of .Net web service which typically returns XML, you can go for HTTP call with JSON response (I've seen it in Asp.net MVC). So that you can easily parse the data on android app.
Added:
HTTP call:
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(getString(R.string.WebServiceURL) + "/cfc/iphonewebservice.cfc?returnformat=json&method=validateUserLogin&username=" + URLEncoder.encode(sUserName) + "&password=" + URLEncoder.encode(sPassword,"UTF-8"));
HttpResponse response = httpClient.execute(httpGet, localContext);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String sResponse = reader.readLine();
JSONObject JResponse = new JSONObject(sResponse);
String sMessage = JResponse.getString("MESSAGE");
int success = JResponse.getInt("SUCCESS")
There are two approaches available to you:
Build an Android app.
Build a webapp, using W3C geolocation to access GPS coordinates. (see geo-location-javascript)
If you go for option (1), you'll want to expose your .NET service as a simple REST API (using JSON as Vikas suggested to make it just that bit simpler!)
Android already comes with all the components needed to access and parse such a REST API, specifically the Apache HTTP and JSON packages, and can be iterated on rather quickly once you have the basic request/parse framework in place.

Post an image from Android client to Rails server without triggering InvalidAuthenticityToken

I'm building an Android app that runs off of a rails server. At first, when I tried to post simple String data to the server, I ran into an InvalidAuthenticityToken issue, but realized that I can bypass the authentication by setting the content type to "json"
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(Constants.REST_HOST + "/add_comment");
post.addHeader("Content-Type", "application/json");
The next step was trying to get upload profile picture working. However, when I tried uploading a photo via a MultipartEntity post, setting the content type to "json" causes the following error
StandardError (Invalid JSON string):
but not setting the content type brings back the InvalidAuthenticityToken exception. What's the correct way to post an image to a rails server from a foreign Java client?
ActionController::InvalidAuthenticityToken
(ActionController::InvalidAuthenticityToken):
Based on Jesse's suggestion, I ended up using
protect_from_forgery :except => :upload_avatar_pic
to disable authenticity check, but only for a specific function, so checks for browser requests are still validated.
You can disable authenticity checking on API non-get calls from non-web clients. You can do this in a before filter
class ApiController < ApplicationController
skip_before_filter :verify_authenticity_token
def create
#or whatever
end
end
The problem solved by Jesse Wolgamott said, but the page show "You are being redirected" message when I submit the form (Update,create,show). In before that the page redirected correctly. I am using rails 2.3.8.how to resolve this?

Categories

Resources