Autor Tema: consulta http  (Leído 4256 veces)

0 Usuarios y 1 Visitante están viendo este tema.

LeandroA

  • Administrador
  • Petabyte
  • *****
  • Mensajes: 1128
  • Reputación: +151/-8
    • Ver Perfil
consulta http
« en: Junio 07, 2013, 07:41:03 pm »
Hola, como se hace una consulta http con android studio, supongamos en en un layout tengo un boton y una caja de texto, presiono el boton hace la consulta a una pagina web y muestra el contenido en la caja de texto (supongamos que la pagina muestra un simple texto plano "hola mundo")

pd: que triste preguntar esto  :D

xkiz ™

  • Moderador Global
  • Gigabyte
  • *****
  • Mensajes: 283
  • Reputación: +30/-11
    • Ver Perfil
    • xkiz ™
Re:consulta http
« Respuesta #1 en: Junio 08, 2013, 03:00:30 pm »
la verdad ni la menor idea pero aca te busque un video tutorial en Youtube, ponelo en la calidad mas alta para que puedas ver bien lo que escribe y saltea a los 5:30 minutos si ya tenes todo instalado..

[youtube]http://www.youtube.com/watch?v=a764vgnOx8o][/youtube]

LeandroA

  • Administrador
  • Petabyte
  • *****
  • Mensajes: 1128
  • Reputación: +151/-8
    • Ver Perfil
Re:consulta http
« Respuesta #2 en: Junio 08, 2013, 08:27:53 pm »
bueno al parecer no es fácil o mejor dicho hay una limitación de seguridad  :-\, probé con dos metodos, pero al parecer, utilizar internet en segundo plano tiene restricciones, las cuales según lei se pueden desbloquearse agregando los permisos en el AndroidManifes.xml, pero aun asi no corre y me tira error

Citar
android.os.NetworkOnMainThreadException

MainActivity.java  (hay dos metodos uno de ellos esta comentado)
Código: (JAVA) [Seleccionar]
package com.example.helloworld;

import android.app.Activity;
import android.os.Bundle;
// used for interacting with user interface
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;
import android.view.View;
// used for passing data
import android.os.Handler;
import android.os.Message;
// used for connectivity
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.os.AsyncTask;
import android.widget.TextView;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

    private static final String TAG = "Test";
    private Button MiBoton;

    private  HttpResponse response;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MiBoton = (Button) findViewById(R.id.button1);

        MiBoton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //Log.v(TAG, "Leandro");

                //HttpClient httpclient = new DefaultHttpClient();
                //HttpGet httpget = new HttpGet("http://www.leandroascierto.com");
                //try{
                    //message.setText("333");
                //    HttpResponse response = httpclient.execute(httpget);
                    //message.setText("444");
                //    StatusLine statusLine = response.getStatusLine();
                //    int statusCode = statusLine.getStatusCode();
                //     if(statusCode == 200){
                //         Log.v(TAG, "sdf");
                //    }else
                //        Log.v(TAG, "mierda");
                //}catch(Exception e){
                //     Log.v(TAG, e.toString());
                //}

                try {

                    // Perform action on click
                    URL url = new URL("http://www.leandroascierto.com");
                    Log.v(TAG,"1");
                    URLConnection conn = url.openConnection();
                    Log.v(TAG,"2");
                    BufferedReader rd = new BufferedReader(new
                            InputStreamReader(conn.getInputStream()));
                    Log.v(TAG,"3");
                    String line = "";
                    while ((line = rd.readLine()) != null) {
                        Message lmsg;
                        lmsg = new Message();
                        lmsg.obj = line;
                        lmsg.what = 0;

                        Log.v(TAG, lmsg.toString());
                    }
                }
                catch (Exception e) {
                    Log.v(TAG, e.toString());
                }

            }
        });

    }

    @Override

    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    protected void onStart(){
        super.onStart();
        //Log.v(TAG, "Leandro Ascierto");
    }

}

AndroidManifest.xml
Código: (JAVA) [Seleccionar]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloworld"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="16" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.helloworld.MainActivity"
            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>

activity_main.xml
Código: (JAVA) [Seleccionar]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:id="@+id/LinearLayout1"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical" >

    <Button
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Button"
            android:id="@+id/button1"
            android:layout_gravity="left|center_vertical"/>
</LinearLayout>

seba123neo

  • Moderador
  • Terabyte
  • *****
  • Mensajes: 763
  • Reputación: +88/-5
    • Ver Perfil
Re:consulta http
« Respuesta #3 en: Junio 09, 2013, 05:29:48 am »
a mi juego me llamaron  8)

te explico como es el tema, ahora lo veo facil, pero en su momento hace unos años cuando empeze me tomo tiempo investigarlo y dejarlo realmente bien.

para explicarlo de forma facil, en android cada cosa necesita su "permiso" (prender wifi, leer contactos, escribir en almacenamiento..etc), como bien hiciste ahi, añadiste el permiso de "internet" en el manifest, eso esta bien, de lo contrario cualquier intento de conexion a internet te salta error.

ahora bien, para hacer una simple peticion a internet, despues de investigar varios metodos para ver cual era el mas rapido, ya hace tiempo que uso este que te paso abajo (es lo mas facil que hay, es simplemente una peticion a una web y una respuesta de texto)

Código: (JAVA) [Seleccionar]
    public static String valida(String pParametro) {

HttpURLConnection vConexion = null;
URL vDireccion;
String vResultado = "";

try {

vDireccion = new URL("http://www.prueba.com/archivo.php?pId=" + pParametro);

vConexion = (HttpURLConnection) vDireccion.openConnection();
vConexion.setConnectTimeout(2000); // Tiempo de espera de la conexion
vConexion.setReadTimeout(10000); // Tiempo de espera de la lectura del stream, si esto ocurre lanza una SocketTimeoutException
vConexion.connect();// Si no conecta lanza una SocketTimeoutException

InputStream vStream = vConexion.getInputStream();

if (vStream.available() != 0){

String vRespuesta = convertInputStreamToString(vStream);

if (vValor.equals("HOLA")) {
vResultado = "OK";
} else {
vResultado = "ERROR";
}

} else {
vResultado = "Error al leer datos del servidor."; // Conecto pero no pudo leer la respuesta (Stream).
}

vDireccion = null;

vStream.close();
vStream = null;

vConexion.disconnect();
vConexion = null;

} catch (SocketTimeoutException e) {
e.printStackTrace();
vResultado = "No se pudo Conectar al Servidor. Chequee la Conexion a Internet y vuelva a intentar.";
} catch (IOException e) {
e.printStackTrace();
vResultado = "No se pudo Conectar al Servidor. Chequee la Conexion a Internet y vuelva a intentar. 2";
}
return vResultado;
}

con eso ya es suficiente, me olvidaba pasarte la funcion que conviente al "stream" que viene de internet (seria la respuesta) a string, aca va:

Código: (JAVA) [Seleccionar]
public static String convertInputStreamToString(InputStream is) throws IOException {

if (is != null) {
Writer writer = new StringWriter();

char[] buffer = new char[500000];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
return writer.toString();
} else {       
return "";
}
}

con eso ya te tiene que funcionar para hacer cualquier cosa.

ahora bien, hay un problema, que seguramente es el que te esta pasando a vos, antes cuando yo programaba con la version 2.1 de android, esto funcionaba de lujo en cualquier lugar de la aplicacion (en el evento de un boton o donde sea), pero despues no me acuerdo desde que version de las nuevas que fueron saliendo, dejo de funcionar y lanzaba error, investigando decian que ya no se pueden hacer conexiones de internet desde el mismo "thread" por asi decirlo que la UI, sino que tenes que meterlo en un thread diferente, si o si, sino te lanza error en las versiones nuevas como la 4.

entonces otra ves investigando, cual es el mejor metodo de hacer "thread" o tareas costosas sin que te trabe la UI, me tope y me enamore de "AsyncTask", aparte de ser la solucion al problema anterior sirve para todo.

aca te paso la base de esa clase, la podes buscar en internet y te dice para que sirve cada evento de los que tiene, podes pasar parametros y actualizar controles de la UI directamente en el evento onProgressUpdate.

Código: (JAVA) [Seleccionar]
private class ThreadActualizar extends AsyncTask<String, String, String> {
    Context ctx;

public ThreadActualizar(Context ctx){
this.ctx = ctx;
}

               @Override
protected void onPreExecute() {

}

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

}
       
               @Override
protected void onProgressUpdate(String... values) {

}

                @Override   
protected void onPostExecute(String result) {

}
}

simplemente poner el codigo que quieras, en este caso la conexion a internet, en el evento doInBackground y listo.

y lo llamas desde afuera de esta forma:

Código: (JAVA) [Seleccionar]
ThreadActualizar thrActualizar = new ThreadActualizar(this);
thrActualizar.execute("");

saludos.

LeandroA

  • Administrador
  • Petabyte
  • *****
  • Mensajes: 1128
  • Reputación: +151/-8
    • Ver Perfil
Re:consulta http
« Respuesta #4 en: Junio 09, 2013, 02:46:14 pm »
Buenísimo Seba, había visto algo de doInBackground pero como todavía no se ni donde estoy pisando lo pase de largo y fui por algo mas facil, asi que era ese el problema,
busque algo con lo que me pasaste porque no se muy que es lo librerias hay que importar y me tope con este ejemplo y bien me funciono bien, al parecer utiliza otras librerias (el tuyo creo que HttpURLConnection y el otro DefaultHttpClient) no se bien que ventajas o desventajas cada uno pero bueno me pone contento almenos poder conectar a la web y ver el contenido.

unas preguntas mas fuera de este tema

que significa o porque se declaran asi

protected void
public static

otra lo que se llama MainActivity.java, es un modulo una clase? por lo que vi se pueden declarar clases privadas dentro de este, se pueden agregar mas archivos de este tipo?

los Layout serian algo asi como los forms en vb?  :P






seba123neo

  • Moderador
  • Terabyte
  • *****
  • Mensajes: 763
  • Reputación: +88/-5
    • Ver Perfil
Re:consulta http
« Respuesta #5 en: Junio 09, 2013, 06:52:25 pm »
es medio dificil explicarlo aca, pero voy a tratar  8)

formularios vb6 = Activities en android

la interfaz y controles de estas "Activities", las programas en xml, en los llamados "layout", pero estos xml no solo pueden ser para "Activities", pueden ser para cualquier cosa..., por ejemplo para un listview, las filas de un listview son layout tambien que se pueden personalizar como quieras, si queres un boton con 3 estados o cosas asi, tambien tenes que programar un layout, o sea todo es un layout de alguna forma.

una pantalla o formulario se compone de una clase, en este caso MainActivity.java, y de su layout respectivo.

fijate que el layout que va a usar la pantalla lo carga en el metodo OnCreate (seria como el load en vb6), en la linea setContentView(R.layout.activity_main);, ahi le esta diciendo que activity_main "sera el layout de la pantalla".

esas .java son clases, y dependiendo de que clase padre se "implemente", sera su funcion real.

o sea esa MainActivity.java, es una pantalla ¿ pero porque ? , pues porque arriba fijate que debe estar implementando de la clase Activity, debe decir algo como "implements activity", entonces eso quiere decir que esa clase se comportara como una pantalla, si le sacas ese implements, te queda una clase vacia como si fuera un modulo bas en visual basic 6 por asi decirlo.

cualquier variable static o método estático puede ser llamado sin necesidad de crear el objeto de la clase, mientras que para usar las variables o métodos no estáticos debes crear el objeto.

void es un metodo que no devuelve nada (como un simple Sub en vb6).

protected quiere decir que solo puede ser accedido por su clase y por clases derivadas.

y te recomiendo que leas esto:

Curso Programación Android – Indice de Contenidos

es un excelente curso de android, en los conceptos generales ya te explica todo esto, y te explica bien la estructura de un proyecto de android layout y demas. te super recomiendo que lo leas desde el principio, cuando lleges al punto 4 ya vas a tener casi todo claro, el tipo programa en eclipse, pero es lo mismo no le des bola a eso, el codigo es el mismo.

saludos.




LeandroA

  • Administrador
  • Petabyte
  • *****
  • Mensajes: 1128
  • Reputación: +151/-8
    • Ver Perfil
Re:consulta http
« Respuesta #6 en: Junio 10, 2013, 02:13:27 pm »
Gracias seba por la explicación, muy buen tutorial esa web

Saludos.

Fakedo0r

  • Bit
  • Mensajes: 4
  • Reputación: +0/-0
  • Fuera de compás en una de las 12 dimensiones.
    • Ver Perfil
Re:consulta http
« Respuesta #7 en: Junio 14, 2013, 04:37:43 pm »
Hola, que tal ¿? Aquí te dejo una pequeña clase que hice hace tiempo para el proyecto del síntesis.
Un dato, si te fijas, la clase extiende a la clase Thread, es porque a partir de API 14 de Android es obligatorio ejecutar las peticiones HTTP en hilos diferentes a la main, en caso contrario, te devolverá un bonito Crash.

Código: (JAVA) [Seleccionar]
public class CLS_HttpRequest extends Thread {

private String sURL;
private String sRespost;

public CLS_HttpRequest(String sURL) {
this.sURL = sURL;
}

public void run() {
HttpClient tHttpClient = new DefaultHttpClient();
HttpResponse tHttpResponse;

try {
tHttpResponse = tHttpClient.execute(new HttpGet(this.sURL));
StatusLine statusLine = tHttpResponse.getStatusLine();

if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
tHttpResponse.getEntity().writeTo(bos);
bos.close();

this.sRespost = bos.toString();
} else {
tHttpResponse.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
e.fillInStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

public String getResponse() {
return this.sRespost;
}
}


También te dejo un pequeño ejemplo por si quieres echar un vistazo: http://www.sendspace.com/file/ahm8mn

EDIT:
Referente a las otras 2 dudas, si tienes conocimientos en POO entonces sera fácil entender.

protected void <== son métodos accesibles solo desde la propia clase y desde subclases.
public static <== los métodos estáticos, para poder llamarlos no hace falta instanciar ninguna clase.

Lo siento, si no me he explicado bien, soy pésimo para explicaciones  ;)

Saludos!
« última modificación: Junio 14, 2013, 04:44:29 pm por Fakedo0r »