I'm using loopj 1.4.4 library to make HTTP request on my android device with 4.2.2.
setTimeout method is not working as expected:
public class RestClient {
private static final int CONNECTION_TIMEOUT = 1000;
private static AsyncHttpClient client = new AsyncHttpClient();
public static void get(String url, RequestParams params,
AsyncHttpResponseHandler responseHandler) {
client.setTimeout(CONNECTION_TIMEOUT);
client.setMaxRetriesAndTimeout(1, CONNECTION_TIMEOUT);
client.get(getAbsoluteUrl(url), params, responseHandler);
}
private static String getAbsoluteUrl(String relativeUrl) {
return Config.API_URL + relativeUrl;
}
}
Using the code above I receive a timeout (specifically a onFailure callback) after
more or less 40 seconds...where am I wrong?
I think my code is not very different from this one: Loopj's AsyncHttpclient not setting the correct timeout
Related
I have a web api controller:
// POST: api/CountriesAPI
[ResponseType(typeof(Country))]
public async Task<IHttpActionResult> PostCountry(Country country)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Countries.Add(country);
await db.SaveChangesAsync();
return CreatedAtRoute("DefaultApi", new { id = country.CountryID }, country);
}
I don't know how how to consume this from android. please help.
I've used the Android HTTP Client available here and found it very simple and easy to use.
You can then do a POST with code something like below:
public class HTTPClient
{
private static AsyncHttpClient client = new AsyncHttpClient();
public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler)
{
client.get(url, params, responseHandler);
}
public static void get(String url, FileAsyncHttpResponseHandler responseHandler)
{
client.get(url, responseHandler);
}
public static void post(Context context, String url, StringEntity entity, String contentType, AsyncHttpResponseHandler responseHandler)
{
client.post(context, url, entity, contentType, responseHandler);
}
}
HTTPClient.post(this, <server_url>, entity, "application/json", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response)
{
// Do Something
}
#Override
public void onFailure(Throwable error, String content)
{
// Do Something else
}
});
You can try Libraries like Volley (Requires you to write boilerplate code) or RetroFit
You can make get and post requests using them, do read about Pojos and model creation before you start. And also how do Callbacks work.
I am trying to upload video files to a Bucket in S3 server from android app using a signed URLs which is generated from server side (coded in python) application. We are making a PUT request to the signed URL but we are getting
connection reset by peer exception.
But when I try the same URL on the POSTMAN REST CLIENT get a success message.
Any help will be appreciated.
Done this using Retrofit HTTP client library,it successfully uploaded file to Amazon s3 server.
code:
public interface UploadService {
String BASE_URL = "https://bucket.s3.amazonaws.com/folder";
/**
* #param url :signed s3 url string after 'BASE_URL'.
* #param file :file to upload,( usage: new TypedFile("mp4", videoFile);.
* #param cb :callback.
*/
#PUT("/{url}")
void uploadFile(#Path(value = "url", encode=false) String url, #Body() TypedFile file, Callback<String> cb);
}
service class
public final class ServiceGenerator {
private ServiceGenerator() {
}
public static <S> S createService(Class<S> serviceClass, String baseUrl) {
return createService(serviceClass, baseUrl, null, null);
}
public static <S> S createService(Class<S> serviceClass, String baseUrl, final String accessToken, final String tokenType) {
class MyErrorHandler implements ErrorHandler {
#Override public Throwable handleError(RetrofitError cause) {
return cause;
}
}
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.registerTypeAdapter(Date.class, new DateTypeAdapter())
.disableHtmlEscaping()
.create();
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(baseUrl)
.setClient(new OkClient(new OkHttpClient()))
.setErrorHandler(new MyErrorHandler())
.setLogLevel(RestAdapter.LogLevel.FULL)
.setConverter(new GsonConverter(gson));
if (accessToken != null) {
builder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
request.addHeader("Accept", "application/json;versions=1");
request.addHeader("Authorization", tokenType +
" " + accessToken);
}
});
}
RestAdapter adapter = builder.build();
return adapter.create(serviceClass);
}
and use:
UploadService uploadService = ServiceGenerator.createService(UploadService.class,UploadService.BASE_URL);
uploadService.uploadFile(remUrl,typedFile,new CallbackInstance());
Use dynamic URL instead of providing the base URL, use #Url instead of #Path and pass a complete URI, encode= false is by default
Eg:
#Multipart
#PUT
#Headers("x-amz-acl:public-read")
Call<Void> uploadFile(#Url String url, #Header("Content-Type") String contentType, #Part MultipartBody.Part part);
I am using RESTful service. After I login I cannot access other services with the app. It says I am not logged in. I believe I am doing something wrong with the HttpClientStack.. Here is the code..
public class HttpClientStackObject {
public static DefaultHttpClient httpClient;
public static HttpClientStack httpClientStack;
public static HttpClientStack getHttpClientStack() {
if(httpClientStack == null){
httpClient = new DefaultHttpClient();
httpClientStack = new HttpClientStack(httpClient);
}
return httpClientStack;
}
}
Login.java
RequestQueue queue = Volley.newRequestQueue(this, HttpClientStackObject.getHttpClientStack());
jsonObjectRequest = new JsonObjectRequest(
Request.Method.POST, URL, jsonOb,
new ResponseListener(), new ErrorListener());
queue.add(jsonObjectRequest);
I used Loopj Android library for Post requests it works fine when I don't use Static Http Client but when I use Static Http Client it does not give any callback here is my code for class of HttpClient
import com.loopj.android.http.*;
public class MyHttpClient {
private static final String BASE_URL = "http://www.google.com";
private static AsyncHttpClient client = new AsyncHttpClient();
public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.post(getAbsoluteUrl(url), params, responseHandler);
System.out.println("post called");
}
public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.get(getAbsoluteUrl(url), params, responseHandler);
}
private static String getAbsoluteUrl(String relativeUrl) {
return BASE_URL + relativeUrl;
}
}
Here is how I call it
MyHttpClient.post("", params, new AsyncHttpResponseHandler(){
#Override
public void onSuccess(String response) {
System.out.println(response);
}
});
and I have added Internet permission in manifest so there is no issue of permissions here
kindly help
I am building a login application in android in which i am hitting a url(with username and password) upto that part it works fine but after that whenever I am hitting a url(once the user is authenticated) , it return nothing(i.e. a error message like please login first). However it works fine in very similar iphone app and on browser.
I got somewhere that it is the error of phpSessionId(i.e. the session is destroyed for further request) and If we want our Android application to stay authenticated on the server side we need to fetch that id after the first connection and then send it in the headers of all our subsequent requests.
But the problem is that I am unable to get the sessionId from header of the first connection and sending it with further request along with the header.
Please give me some codes or links to complete the task properly.
Thanks.
Finally I solved the issue of session handling in Android.
Android cant handle the session itself(which a simple browser can) so we have to handle it explicitly.
I changed the code for http connection a bit.
Created an instance of DefaultHttpClient in the first Activity when connection established.
public static DefaultHttpClient httpClient;
For the first time connection,I did the following:
URL url=new URL(urlToHit);
LoginScreen.httpClient = new DefaultHttpClient(); //LoginScreen is the name of the current Activity
HttpPost httppost = new HttpPost(url.toString());
HttpResponse response = LoginScreen.httpClient.execute(httppost);
xr.parse(new InputSource(url.openStream())); //SAX parsing
Now for all further connections I used the same httpClient
For example in the next activity:
URL url=new URL(urlToHit);
HttpPost httppost = new HttpPost(url.toString());
HttpResponse response = LoginScreen.httpClient.execute(httppost);
// Log.v("response code",""+response.getStatusLine().getStatusCode());
// Get hold of the response entity
HttpEntity entity = response.getEntity();
InputStream instream = null;
if (entity != null) {
instream = entity.getContent();
}
xr.parse(new InputSource(instream)); //SAX parsing
Hope this will help you all too to solve session issue in Android.
The best idea is to put all the function that your server do in on unique class which is going to be call by the tasks which want to connect. I call this class WebServiceManager. This class have exactly the same method than the server.
As you want an unique session do :
private static WebServiceManager wsm = null;
public static WebServiceManager getInstance() {
if (wsm == null) {
wsm = new WebServiceManager();
}
return wsm;
}
private final HttpClient httpClient;
private WebServiceManager() {
httpClient=new DefaultHttpClient();
}
and then you call the method of your instance of webServiceManager to use always the same session. :)
My problem was that i login first and saved the returned session in userpreferences.
After that the POST call to set a record said
"Error ,Cannot authenticate the User"
So i added
post.setHeader("oAuth-Token", UserPreferences.ACCESS_TOKEN);
the whole thing looks like this.
HttpPost post=new HttpPost(URL );
post.setHeader("oAuth-Token", UserPreferences.ACCESS_TOKEN);
.
.
and It solved the problem.
I wrote a post about it a while back on coderwall
It uses the HttpRequestInterceptor and HttpResponseInterceptor classes which are perfect for that kind of scenario.
Here is an example:
public class HTTPClients {
private static DefaultHttpClient _defaultClient;
private static String session_id;
private static HTTPClients _me;
private HTTPClients() {
}
public static DefaultHttpClient getDefaultHttpClient(){
if ( _defaultClient == null ) {
_defaultClient = new DefaultHttpClient();
_me = new HTTPClients();
_defaultClient.addResponseInterceptor(_me.new SessionKeeper());
_defaultClient.addRequestInterceptor(_me.new SessionAdder());
}
return _defaultClient;
}
private class SessionAdder implements HttpRequestInterceptor {
#Override
public void process(HttpRequest request, HttpContext context)
throws HttpException, IOException {
if ( session_id != null ) {
request.setHeader("Cookie", session_id);
}
}
}
private class SessionKeeper implements HttpResponseInterceptor {
#Override
public void process(HttpResponse response, HttpContext context)
throws HttpException, IOException {
Header[] headers = response.getHeaders("Set-Cookie");
if ( headers != null && headers.length == 1 ){
session_id = headers[0].getValue();
}
}
}
}
Here is an another implementation using Volley library ... a very useful hint from https://stackoverflow.com/a/36496607/3099185
CustomRequest jsonObjReq = new CustomRequest(Request.Method.GET,
url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
}
}, new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
// hide the progress dialog
}
});
Custom request class
import android.util.Log;
import com.android.volley.AuthFailureError;
import com.android.volley.Response;
import com.android.volley.toolbox.JsonObjectRequest;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class CustomRequest extends JsonObjectRequest {
private String session_id = "";
public CustomRequest(int method, String url, JSONObject jsonRequest,
Response.Listener listener, Response.ErrorListener errorListener) {
super(method, url, jsonRequest, listener, errorListener);
}
public CustomRequest(int method, String url, JSONObject jsonRequest, String session_id,
Response.Listener listener, Response.ErrorListener errorListener) {
super(method, url, jsonRequest, listener, errorListener);
this.session_id = session_id;
}
#Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap();
Log.d(TAG, " -> session_id = " + session_id);
if(!(session_id.equals(""))) {
headers.put("Cookie", this.session_id);
}
return headers;
}
}
Simple way of implementing volley using singleton pattern
http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/
Remember to initialize mRequestQueue in onCreate() to avoid unexpected null pointer exception
#Override
public void onCreate() {
super.onCreate();
// initialize the singleton
sInstance = this;
mRequestQueue = Volley.newRequestQueue(this);
}
Hope this help too ... ! :)