Como extraer(descargar) imagenes desde una webservices con base de datos mysql en android

Hola amigos, espero hayan pasado excelentes fiestas y empiezen el año 2018 con muchas ganas de salir adelante, a pedido de un usuario concurrente vamos a ver un nuevo tutorial:


Como extraer(descargar) imágenes desde una webservices con base de datos mysql en Android Studio

Estructura:

Clases:

  • Conector
  • DataParser
  • DescargarImagen
  • Fruta
  • FrutaAdapter
  • MainActivity

Layout

  • activity_main.xml
  • content_main.xml
  • lista.xml

Drawable

  • fruits.png
  • ic_launcher.png
  • placeholder.png

WebServices

  • listar-fruta.php

Base de Datos

  • lista_imagen

Empezamos con la WebServices

WebServices

Debemos tener la siguiente estructura:

listar-fruta.php

<?php
$host='localhost';
$username='root';
$password='12345';
$db="lista_imagen";
$con=mysqli_connect($host,$username,$password,$db) or die('No puede conectarse');
if(mysqli_connect_error($con))
{
echo "Error al conectarse a la base de datos".mysqli_connect_error();
}
$sql="SELECT * from imagen";
$resultado=mysqli_query($con,$sql);
if($resultado)
{
while($row=mysqli_fetch_array($resultado))
{
$data[]=$row;
}

print(json_encode($data));
}
mysqli_close($con);
?>

Continuando la estructura dentro de la capeta imágenes debemos pegar las imágenes acorde a cada uno de nuestros registros, en mi caso como son frutas queda como la siguiente imagen:

Base de datos
lista_imagen

CREATE TABLE `imagen` (
`codigo` int(11) NOT NULL,
`nombre` varchar(100) NOT NULL,
`url` varchar(150) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `imagen` (`codigo`, `nombre`, `url`) VALUES
(1, 'MANZANA', 'manzana.png'),
(2, 'BANANA', 'banana.png'),
(3, 'MANGO', 'mango.png'),
(4, 'UVA', 'uva.png');

Clases
Conector

public class Conector {
public static HttpURLConnection connect(String urlAddress)
{
try {
URL url=new URL(urlAddress);
HttpURLConnection con= (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setConnectTimeout(20000);
con.setReadTimeout(20000);
con.setDoInput(true);
return con;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

DataParser

public class DataParser extends AsyncTask<Void,Void,Integer> {
Context c;
String jsonData;
ListView listaFrutas;
ProgressDialog pd;
public static final String
URL_IMAGENES = "http://192.168.8.133/imagen/imagenes/";
ArrayList<Fruta> frutas =new ArrayList<>();
public DataParser(Context c, String jsonData, ListView listaFrutas) {
this.c = c;
this.jsonData = jsonData;
this.listaFrutas = listaFrutas;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
pd=new ProgressDialog(c);
pd.setTitle("Parse");
pd.setMessage("Analizando ... Por favor espere");
pd.show();
}
@Override
protected Integer doInBackground(Void... params) {
return this.parseData();
}
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
pd.dismiss();
if(result==0)
{
Toast.makeText(c,"No se puede analizar", Toast.LENGTH_SHORT).show();
}else {
FrutaAdapter adapter=new FrutaAdapter(c, frutas);
listaFrutas.setAdapter(adapter);
}
}
private int parseData()
{
try
{
JSONArray ja=new JSONArray(jsonData);
JSONObject jo=null;
frutas.clear();
Fruta fruta;
for(int i=0;i<ja.length();i++)
{
jo=ja.getJSONObject(i);
int id=jo.getInt("codigo");
String nombre=jo.getString("nombre");
String imagen=jo.getString("url");
fruta =new Fruta();
fruta.setCodigo(id);
fruta.setNombre(nombre);
fruta.setImageUrl(URL_IMAGENES+imagen);
frutas.add(fruta);
}
return 1;
} catch (JSONException e) {
e.printStackTrace();
}
return 0;
}
}

DescargarImagen

public class DescargaImagen extends AsyncTask<Void,Void,String> {
Context c;
String urlAddress;
ListView lv;
ProgressDialog pd;
public DescargaImagen(Context c, String urlAddress, ListView lv) {
this.c = c;
this.urlAddress = urlAddress;
this.lv = lv;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
pd=new ProgressDialog(c);
pd.setTitle("Recuperar");
pd.setMessage("Recuperando ... Por favor espere");
pd.show();
}
@Override
protected String doInBackground(Void... params) {
return downloadData();
}
@Override
protected void onPostExecute(String jsonData) {
super.onPostExecute(jsonData);
pd.dismiss();
if(jsonData==null)
{
Toast.makeText(c,"Sin éxito, sin datos recuperados",Toast.LENGTH_SHORT).show();
}else {
//PARSE
DataParser parser=new DataParser(c,jsonData,lv);
parser.execute();
}
}
private String downloadData()
{
HttpURLConnection con= Conector.connect(urlAddress);
if(con==null)
{
return null;
}
try
{
InputStream is=new BufferedInputStream(con.getInputStream());
BufferedReader br=new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer jsonData=new StringBuffer();
while ((line=br.readLine()) != null)
{
jsonData.append(line+"n");
}
br.close();
is.close();
return jsonData.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

Fruta

public class Fruta {
int codigo;
String nombre;
String url;
public int getCodigo() {
return codigo;
}
public void setCodigo(int id) {
this.codigo = id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getUrl() {
return url;
}
public void setImageUrl(String url) {
this.url = url;
}
}



FrutaAdapter

public class FrutaAdapter extends BaseAdapter {
Context c;
ArrayList<Fruta> frutas;
LayoutInflater inflater;
public FrutaAdapter(Context c, ArrayList<Fruta> frutas) {
this.c = c;
this.frutas = frutas;
inflater= (LayoutInflater)
c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return frutas.size();
}
@Override
public Object getItem(int position) {
return frutas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
if(convertView==null)
{
convertView=inflater.inflate(R.layout.lista,parent,false);
}
TextView mombre= (TextView) convertView.findViewById(R.id.txtNombre);
ImageView img= (ImageView) convertView.findViewById(R.id.Imagen);
Fruta fruta = frutas.get(position);
mombre.setText(fruta.getNombre());
PicassoClient.downloadImage(c, fruta.getUrl(),img);
return convertView;
}
}

MainActivity

public class MainActivity extends AppCompatActivity {
final static String
URL_WEB_SERVICE="http://192.168.8.133/imagen/web-service/listar-fruta.php";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
final ListView lv= (ListView) findViewById(R.id.lvFrutas);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new DescargaImagen(MainActivity.this,URL_WEB_SERVICE,lv).execute();
}
});
}
}


Layout

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.androfast.pc.appimagenbd.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_menu_send" />
</android.support.design.widget.CoordinatorLayout>

content_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.androfast.pc.appimagenbd.MainActivity"
tools:showIn="@layout/activity_main">
<ListView
android:id="@+id/lvFrutas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>

lista.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_margin="10dp"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp"
android:layout_height="150dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="174dp"
android:layout_height="wrap_content"
android:id="@+id/Imagen"
android:padding="10dp"
android:src="@drawable/fruits" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Nombre"
android:id="@+id/txtNombre"
android:padding="10dp"
android:textColor="@color/colorAccent"
android:layout_alignParentLeft="true"
/>
</LinearLayout>
</android.support.v7.widget.CardView>

Drawable

Estas imágenes deben guardarlos en tu carpeta Drawable

Ahora en nuestro AndroidManifest debemos agregar el siguiente permiso:
<uses-permission android:name=”android.permission.INTERNET”/>

Ahora en nuestro build.gradle debemos agregar lo siguiente:
    compile ‘com.android.support:design:26.0.0-alpha1’
    compile ‘com.android.support:cardview-v7:26.0.0-alpha1’
    compile ‘com.squareup.picasso:picasso:2.5.2’

y en el mismo archivo de buil.gradle en los corchetes de android agregamos lo siguiente:
 useLibrary ‘org.apache.http.legacy’

sino sabes donde te dejo la siguiente imagen:

18 comentarios en «Como extraer(descargar) imagenes desde una webservices con base de datos mysql en android»

  1. SoCu

    Gracias por este nuevo tutorial, y aprovecho este post para felicitarte el año nuevo, que ni si quiera lo hice después de enviarte unos correos.
    Al ver este tutorial de base de datos me gustaría preguntarte si se puede crear un archivo de base de datos desde Windows para luego poner ese archivo de BD en la aplicación y leer los datos de ahí, los datos que tendría serian fotos, texto y teléfonos, una especie de agenda, para luego hacer llamadas, y de ser posible protegida para no poder ser manipulada, igual la pregunta es tonta, pero eso se puede hacer, o las BS se tienen que crear a base de código desde Andoid Studio?

  2. AndroFast

    Hola Socu te respondí por correo tu duda y gracias por la felicitación que tu también tengas un buen año, con respecto a la duda de la BD, déjame decirte que android puede conectarse a casi cualquier gestor de BD por ejemplo se me ocurre que podrías usar postgresql y su gestor PgAdmin que es un gestor en windows y linux se le puede poner contraseña para que nadie mas vea o toque tu BD.

  3. SoCu

    Gracias voy a ver que hay sobre PostgreSQL y PgAdmin, a ver si admite poner archivos jpg, lo que he visto por algun video es que android studio no admite base de datos con mas de 1 Mb, no se si esto es asi, lo digo porque si le voy a poner fotos la base de datos pesara mucho mas de 1 Mb.

  4. AndroFast

    Hola de nuevo Socu, me temo que has entendido mal ninguna BD guarda las imágenes, las imaegenes quedan guardadas en tu webservices y solo la dirección de las imágenes se guardan en la BD, asi como esta este tutorial, como veo que aun eres novato te invito a la sección de aprender fácil que esta en nuestro menu, te apuesto que después de eso entenderás muchas cosas y no tendrás problemas con nuestros ejercicios.

  5. SoCu

    Hola, no Alex, bueno creo que androfast eres tu Alex, como no hay un sitio o foro donde preguntar, lo hice aquí que se habla del tema, no tiene nada que ver con lo que explicas aquí, igual me he expresado mal, pero lo que busco es crear un archivo de BD en Windows para ponerlo luego dentro de Android Studio, nada de poner la BD en un servidor para que se tenga que conectar a internet para buscar información, aunque tampoco tengo un servidor, y luego si la BD contiene imágenes y no se pueden poner dentro de la BD porque tienen que estar en el servidor, pues en su lugar no sé si se pueden poner en la carpeta “assets”, por otro lado he buscado información sobre PostgreSQL y no he conseguido encontrar nada como poner el archivo de BD dentro de Android Studio, sí que hay como crear la BD, pero nada más, igual en videotutoriales que este en inglés se dice como, pero yo no tengo ni idea de inglés.
    en el menú de sección de aprender fácil sí que la he repasado y descargado las paginas para poder verlas luego cuando no tenga conexión a internet, pero lo que busco hacer no he conseguido sacarlo de ahí por eso te he preguntado por correo alguna cosa, como por ejemplo algo que acabo de ver, es como cambiar el icono a una aplicación, lo que intento también es cambiar el nombre que aparece en el icono de la aplicación, sí que consigo cambiarlo, pero a la vez se cambia el nombre que tengo puesto en el Toolbar, y quiero que tengan nombres diferentes, he visto mucha información, pero tampoco lo he conseguido. Bueno no sigo, que me parece que me he extendido un poco, jeje.

  6. Del Matorral

    Hola buenas…tengo una duda sin resolver. ¿Para montar una imagen en un ImageView desde el web service, es necesario la descarga de la foto o se puede “linkar” desde el servidor al terminal o al revés?. Si es imprescindible descargar la foto, en un ListView con muchos item con una foto cado uno ¿no será demasiado “pesado” o llenará en exceso de imágenes la memória del terminal? Espero haberme explicado bien. Un saludo.

    1. ANDROFAST Autor

      Lo genial de programar es que los limites de hacer algo están en tu imaginación, pero lo mas normal al tratar las imágenes es la siguiente: las imágenes están guardadas en una carpeta de la web services y en la base de datos solo esta el nombre de la ruta de dicha imagen. He listado 50 imágenes en un listview sin problemas, habría que saber cuantas imágenes querrás listar tu?

      1. Del Matorral

        Gracias por tu respuesta, pero no iba por ahí la pregunta. Por ejemplo: la app de Facebook o instagram están muy nutridas de imágenes. Esa cantidad de imágenes las ves en tu terminal, pero no están en tu terminal ¿o si?. Es como en una web que presenta imágenes mudiante url, pero esas imágenes no están en el server que aloja esa web que las visualiza. Es la duda que tengo.
        Reitero el agradecimiento por tu rápida respuesta.
        Un saludo.

  7. Del Matorral

    Ja, ja, ja…nada, que no lo acabo de tener claro. Vengo de PHP, y Java me está volviendo loco. Tan sólo el hecho de tener que “tipar” las variables me causa más de un quebradero de cabeza. Así que manos al teclado y al lío.
    Gracias por tus respuestas.

    1. ANDROFAST Autor

      Creo que una imagen vale mas que unas cuantas palabras y si aun así no me dejo entender he fallado como el profe Andro jaja
      null
      Según la imagen me tomo una foto con mi celular por ejemplo, esta por medio de su aplicación hace conexión con su webservices y la almacena en cualquier servidor de archivos de su pertenencia, luego puedo ver esa misma imagen desde cualquier tipo de aplicación que tenga acceso a consultar su servidor.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

WhatsApp chat