¿Cómo llamar a un método RESTful desde Android?

He intentado dos formas diferentes de llamar a un método REST simple desde Android; dicho método REST, que funciona desde otros clientes, simplemente devuelve un valor int como 17.

Los dos intentos siguientes se basaron en el código que encontré en línea. Uno es así:

public void onFetchBtnClicked (Ver v) {if (v.getId () == R.id.FetchBtn) {Toast.makeText (getApplicationContext (), "Has aplastado el botón, amigo", Toast.LENGTH_SHORT) .show () ; nueva NetworkTask (). execute (); }}

clase estática pública NetworkTask extiende AsyncTask {

@Override
protected String doInBackground(Void... params) {
    final String TAG;
    TAG = "callWebService";
    String deviceId = "Android Device";

    HttpClient httpclient = new DefaultHttpClient();
    HttpGet request = new HttpGet("http://localhost:28642/api/Departments/GetCount");
    request.addHeader("deviceId", deviceId);

    ResponseHandler<String> handler = new BasicResponseHandler();
    String result = "";

    try
    {
        result = httpclient.execute(request, handler);
    }
    catch (ClientProtocolException e)
    {
        e.printStackTrace();
        Log.e(TAG, "ClientProtocolException in callWebService(). " + e.getMessage());
    }
    catch (IOException e)
    {
        e.printStackTrace();
        Log.e(TAG, "IOException in callWebService(). " + e.getMessage());
    }

    httpclient.getConnectionManager().shutdown();
    Log.i(TAG, "**callWebService() successful. Result: **");
    Log.i(TAG, result);
    Log.i(TAG, "*****************************************");

    return result;
}

@Override
protected void onPostExecute(String result) {
    final String TAG;
    TAG = "onPostExecute";
    if (null != result)

Log.i (TAG, resultado); }

Con el código anterior, después de que falle la siguiente línea de código:

result = httpclient.execute(request, handler) ;

...Yo obtengo, "*E/callWebService﹕ IOException in callWebService(). Connection to http://localhost:28642 refused*"

Este problema puede ser un problema de subprocesos, ya que leí esto en el libro "Programando Android" de O'Reilly de Mednieks, Dornin, Meike y Nakamura: "AsyncTask es una herramienta conveniente para ejecutar tareas pequeñas y asincrónicas. ¡Solo recuerda que el método doInBackground se ejecuta en un hilo diferente! No debe escribir ningún estado visible desde otro hilo ni leer ningún estado que se pueda escribir desde otro hilo. Esto incluye sus parámetros".

Con mi otro intento:

public void onFetchBtnClicked(View v){
    if(v.getId() == R.id.FetchBtn){
        Toast.makeText(getApplicationContext(), "You mashed the button, dude.", Toast.LENGTH_SHORT).show();
        callWebService("http://localhost:28642/api/Departments/GetCount");
    }
}

public String callWebService(String requestUrl)
{
    final String TAG;
    TAG = "callWebService";
    String deviceId = "Android Device";

    HttpClient httpclient = new DefaultHttpClient();
    HttpGet request = new HttpGet(requestUrl);
    request.addHeader("deviceId", deviceId);

    ResponseHandler<String> handler = new BasicResponseHandler();
    String result = "";

    try
    {
        result = httpclient.execute(request, handler);
    }
    catch (ClientProtocolException e)
    {
        e.printStackTrace();
        Log.e(TAG, "ClientProtocolException in callWebService(). " + e.getMessage());
    }
    catch (IOException e)
    {
        e.printStackTrace();
        Log.e(TAG, "IOException in callWebService(). " + e.getMessage());
    }

    httpclient.getConnectionManager().shutdown();
    Log.i(TAG, "**callWebService() successful. Result: **");
    Log.i(TAG, result);
    Log.i(TAG, "*****************************************");

    return result;
}

... el depurador me descarga en View.class después de tocar la misma línea de problema (resultado = httpclient.execute (solicitud, controlador)). Por qué hace eso, no sé *, pero creo que el quid del problema, como lo indica err msgs en logcat, es: "Causado por: android.os.NetworkOnMainThreadException"

* Tal vez porque se está intentando algo desagradable dentro del hilo de la interfaz de usuario (Ver).

Además (no es gran cosa, pero "interesante", tal vez): el Toast no aparece cuando se realiza una llamada al método después (funciona de otra manera).

El servidor (Web API) tiene un punto de interrupción establecido en su método de controlador correspondiente, pero nunca se alcanza. Como se mencionó, el servidor se está ejecutando y responde muy bien a otros clientes (aplicaciones de Windows).

Debe haber una forma algo directa de llamar a un método RESTful desde Android. ¿Pero qué / cómo?

ACTUALIZAR

Lo intentéesta, ahora, también, llamándolo así:

RestClient client = new RestClient("http://localhost:28642/api/Departments/GetCount");

    try {
        client.Execute(RestClient.RequestMethod.GET);
    } catch (Exception e) {
        e.printStackTrace();
    }

    String response = client.getResponse();
    Log.i("CZECH_THIS", response);

... pero también está (o parece, de todos modos) feliz de lanzar la excepción "NetworkOnMainThread".

ACTUALIZACIÓN 2

Esto es lo más cerca que he llegado hasta ahora, creo. Quizás el servidor sea el culpable en este caso, porque con este código:

public void onFetchBtnClicked(View v){
    if(v.getId() == R.id.FetchBtn){
        Toast.makeText(getApplicationContext(), "You mashed the button, dude.", Toast.LENGTH_SHORT).show();
    new CallAPI().execute("http://localhost:28642/api/Departments/GetCount");
    }
}

public static class CallAPI extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... params) {

        String urlString=params[0]; // URL to call
        String resultToDisplay = "";
        InputStream in = null;

        // HTTP Get
        try {
            URL url = new URL(urlString);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            in = new BufferedInputStream(urlConnection.getInputStream());

        } catch (Exception e ) {
            System.out.println(e.getMessage());
            return e.getMessage();
        }
        return resultToDisplay;

    }

    protected void onPostExecute(String result) {
        Log.i("FromOnPostExecute", result);
    }

} // end CallAPI

.... la excepción que se lanza es:

libcore.io.ErrnoException: error de conexión: ECONNREFUSED (conexión rechazada) no se pudo conectar a localhost / 127.0.0.1 (puerto 28642): error de conexión: ECONNREFUSED (conexión rechazada)

... y la aplicación de Android continúa ejecutándose (se cae en los otros ejemplos).

¿Por qué mi servidor rechaza la conexión?

ACTUALIZACIÓN 3

Pensé por un minuto que lo tenía: olvidé pasar el número de serie con la URL. Pero incluso después de hacerlo, falla.

Tengo un punto de interrupción en la aplicación del servidor, en el método Controlador; también, en el método Repository, pero nunca se alcanzan.

¿Qué podría estar mal?

¿Es "localhost" el uso incorrecto (en la URL)? ¿Debo usar el nombre de la computadora en su lugar?

¿La URL (pasada literalmente como "http://localhost:28642/api/Departments/GetCount?serialNum=4242") necesita ser verbatimized?

ACTUALIZACIÓN 4

Al cambiar el "locohost" por el nombre de la máquina, aparece "No hay dirección asociada con el nombre de host", así que ese no es el problema ...

Curiosamente, sin embargo, esta línea funciona bien:

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

... mientras que esta es la última línea antes de que se lance / capture la excepción:

in = new BufferedInputStream(urlConnection.getInputStream());

Mirando aestaSin embargo, tal vez necesito escapar de mis golpes; pero cuando ya tienes doble golpe, como después de "http:", ¿tienes que hacer triple golpe? ¿O cuádruples golpes? Seguramente no la cera del techo ...?

Respuestas a la pregunta(1)

Su respuesta a la pregunta