Carlos Herrera Plata
Carlos Herrera Plata

Reputation: 993

Trying to get a json response from API web to Android with android-async-http lib

I've been working with android-async-http (http://loopj.com/android-async-http/) lib with android but for some reason I can't catch the response from server, I know that the server receive and do the things that should do, but I can't get the response for no reason.

Here is the method that calls the API:

public User registUser(String mail, String pass) throws UnsupportedEncodingException {
    final User user = new User();
    user.setToken("enter");

    String bodyAsJson = "{\"user\":{\"email\":\""+mail+"\",\"password\":\""+pass+"\"}}";

    StringEntity entity  = new StringEntity(bodyAsJson);
    Header[] headers = {
            new BasicHeader("Content-type", "application/json")
    };

    client.post(this.context, "http://104.131.189.224/api/user", headers , entity, "application/json",  new JsonHttpResponseHandler() {

        @Override
        public void onSuccess(int statusCode, Header[] headers, JSONObject json) {
            try {
                json = json.getJSONObject("user");
                user.setId(json.getInt("id"));
                user.setEmail(json.getString("email"));
                user.setPassword("123456");
                user.setToken(json.getString("auth_token"));
            } catch ( JSONException e) {
                user.setToken("not json");
            } catch (Exception e) {
                user.setToken("error ");
            }
        }

        @Override
        public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
            user.setToken("comes json array");
        }

        @Override
        public void onSuccess(int statusCode, Header[] headers, String responseString) {
            user.setToken(responseString);
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
            user.setToken("error");
        }

        @Override
        public void onRetry(int retryNo) {
            user.setToken("nothing");
        }
    });

    return user;
}

when I call the method, the user.getToken shows only the "enter" that I put in the beginin, that means, never entered in the onSuccess, onFailure, or onRetry methods.

but I know that the server receive my request because the server log shows: (example: email: [email protected], pass: prueba)

"=>"[email protected]", "password"=>"[FILTERED]"}}                              
    D, [2015-03-17T05:15:27.660562 #28450] DEBUG -- :    (0.8ms)  BEGIN
    D, [2015-03-17T05:15:27.671126 #28450] DEBUG -- :   User Exists (2.6ms)  SELECT
    1 AS one FROM `users` WHERE `users`.`email` = BINARY '[email protected]' LIMIT
    1
    D, [2015-03-17T05:15:27.677448 #28450] DEBUG -- :   SQL (1.0ms)  INSERT INTO `us
    ers` (`email`, `encrypted_password`, `created_at`, `updated_at`) VALUES ('carlos
    @prueba.com', '$2a$10$Dg358IzoaG5KVJ8ZJTeViev2v5B9CAnAqIYI1Zd4EIFC.0Mh.nMU6', '2
    015-03-17 05:15:27.672898', '2015-03-17 05:15:27.672898')                       
    D, [2015-03-17T05:15:27.681514 #28450] DEBUG -- :    (2.0ms)  COMMIT
    D, [2015-03-17T05:15:27.684634 #28450] DEBUG -- :   User Exists (0.6ms)  SELECT
    1 AS one FROM `users` WHERE `users`.`auth_token` = '6aff3b4162cfcf3062a6db12a1c
    ee2bc' LIMIT 1                                                                  
    D, [2015-03-17T05:15:27.685582 #28450] DEBUG -- :    (0.2ms)  BEGIN
    D, [2015-03-17T05:15:27.690901 #28450] DEBUG -- :   SQL (0.8ms)  UPDATE `users`
    SET `auth_token` = '6aff3b4162cfcf3062a6db12a1cee2bc', `updated_at` = '2015-03-1
    7 05:15:27.687516' WHERE `users`.`id` = 11                                      
    D, [2015-03-17T05:15:27.693809 #28450] DEBUG -- :    (1.8ms)  COMMIT
    I, [2015-03-17T05:15:27.698987 #28450]  INFO -- :   Rendered api/users/_user.jso
    n.jbuilder (0.3ms)
    I, [2015-03-17T05:15:27.700292 #28450]  INFO -- :   Rendered api/users/create.js
    on.jbuilder (3.2ms)
    I, [2015-03-17T05:15:27.701395 #28450]  INFO -- : Completed 200 OK in 223ms (Vie
            ws: 6.3ms | ActiveRecord: 10.0ms)

the server should response a json in the format:

{"user":{"id":3,"email":"[email protected]","auth_token":"dc45800fddee07cf9b300d2765283cb2"}}

Upvotes: 0

Views: 517

Answers (1)

Stephen Miller
Stephen Miller

Reputation: 174

Most tutorials are outdated and try to use the apache library however I did find a working one.

While trying to manipulate a Team Treehouse Tutorial ( https://teamtreehouse.com/library/build-a-weather-app/ ) to work for an event finder api instead of their weather api, I ran into the same problem.

They use the OkHttp library

  1. compile the OkHttp library into your build.gradle file under Module:app

compile 'com.squareup.okhttp:okhttp:2.4.0'

this is the most recent version as of 7/9/15

  1. visit the api url to see if you are indeed retrieving the data and that it is in the correct format. For me I was using Eventful.com and finding events in my area. ( https://api.eventful.com/json/events/search?l=arizona&within=15&units=miles&app_key= ) where my app key would go after the "=" at the end of the url.

at this point everything was working great, now I needed to add the OkHttp code to download the json data

  1. add internet permissions to your manifest

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.thestephenmiller.myApp" > <uses-permission android:name="android.permission.INTERNET" /> </manifest>

  1. Open the class or activity where the request will be made and add the following code.

String eventfulUrl = "https://api.eventful.com/json/events/search?l=arizona&within=15&units=miles&app_key="+apiKey; OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url(eventfulUrl) .build();

and make the call

` 
Call call = client.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Request request, IOException e) {

        }

        @Override
        public void onResponse(Response response) throws IOException {
            try {
                if (response.isSuccessful()) {
                    Log.v(TAG, response.body().string());
                }
            } catch (IOException e) {
                Log.e(TAG, "Exception Caught: ", e);
            }
        }
    });

all of which was added to onCreate()

this line Log.v(TAG, response.body().string()); is what outputs the response to the log and is in the if statement where you can deal with the data.

The code will not get the response if the url does not start with "http://" or "https://" however the app will still run error free

Upvotes: 0

Related Questions