Spanish B4A- Descargar archivo de imagen a DirAssets

ferpahud

Active Member
Licensed User
Hola buenos dias, queria saber si hay posibilidades de descargar un archivo de imagen a DirAssets, es decir a la carpeta "Files Manager", donde tengo los demás archivos de mi aplicación.

Intente utilizando el siguiente metodo:
B4X:
Sub descargarImagenes
    hilo.Initialize("hilo",Me)
    For Each imagenItem In lstImagenesPendientes
        hilo.Download("http://centrocomercialva.com.ar/imagenes/" & imagenItem)
        Log(imagenItem & " - Descargada")
    Next
End Sub

Pero no estoy seguro si realmente descarga el arhivo en el dispositivo, o solo muestra el contenido de la url. En caso de descargarlo, ¿Donde lo descarga? ¿Puedo hacer que lo descargue en DirAssets?

Muchas gracias!
 

JordiCP

Expert
Licensed User
Longtime User
DirAssets es un directorio especial de solo lectura en el que se "empaquetan" los recursos de tu aplicación al compilar. De hecho está comprimido, por lo que algunas funciones no pueden acceder a él directamente y es necesario hacer copia antes a otros directorios
Depende del acceso que le quieras dar a los archivos descargados, prueba con File.DirInternal, File.DirDefaultExternal, File.DirRootExternal, ...
 

ferpahud

Active Member
Licensed User
DirAssets es un directorio especial de solo lectura en el que se "empaquetan" los recursos de tu aplicación al compilar. De hecho está comprimido, por lo que algunas funciones no pueden acceder a él directamente y es necesario hacer copia antes a otros directorios
Depende del acceso que le quieras dar a los archivos descargados, prueba con File.DirInternal, File.DirDefaultExternal, File.DirRootExternal, ...

Y como hago para indicar, por ejemplo que guarde la imagen que estoy descargando en File.DirInternal?
 

ferpahud

Active Member
Licensed User

Intento probando las distintas opciones: File.DirInternal, File.DirDefaultExternal, File.DirRootExternal, ... pero no lo consigo. Para que pueda entender un poco, lo que intento hacer es listar una serie de comercios, ya tengo la imagen de algunos comercios en la app, pero si agrego uno nuevo, quiero que la imagen se descargue donde ya tengo las demas imagenes, esto es nececesario ya que descargo los comercios de una base de datos externa (actualizo) recorro las imagenes existentes, si la imagen de algun comercio no se encuentra dentro de las existentes la tengo que descargar, para luego mostrarla. El Hilo orginial sobre este proyecto es el siguiente: https://www.b4x.com/android/forum/threads/solucionado-b4a-cargar-imagen-desde-url.79589/#post-508747 Pero como el tema fue mutando decidi abrir un nuevo hilo para esta consulta.

Saludos!
 

JordiCP

Expert
Licensed User
Longtime User
Acabo de mirar el hilo.

En DirAssets sólamente pueden haber imágenes que hayas puesto en el momento de compilar, es un directorio de solo lectura

Puedes hacer dos cosas:
  • La primera vez que se ejecuta la aplicación, copias TODOS los que tengas en DirAssets hacia DirInternal, y también los descargas ahí, así tienes un solo directorio que comprobar antes de lanzar el HttpJob
o bien
  • Cuando tengas que comprobar si un fichero ya lo tienes, buscas tanto en DirAssets (donde estarán los que ya tenía tu aplicación en el momento de compilar) como en DirInternal (donde estarán los que has ido descargando). Si no existe, lanzas un HttpJob, y cuando se termine de descargar (o sea, en el evento JobDone), lo guardas en DirInternal
 

ferpahud

Active Member
Licensed User
Acabo de mirar el hilo.

En DirAssets sólamente pueden haber imágenes que hayas puesto en el momento de compilar, es un directorio de solo lectura

Puedes hacer dos cosas:
  • La primera vez que se ejecuta la aplicación, copias TODOS los que tengas en DirAssets hacia DirInternal, y también los descargas ahí, así tienes un solo directorio que comprobar antes de lanzar el HttpJob
o bien
  • Cuando tengas que comprobar si un fichero ya lo tienes, buscas tanto en DirAssets (donde estarán los que ya tenía tu aplicación en el momento de compilar) como en DirInternal (donde estarán los que has ido descargando). Si no existe, lanzas un HttpJob, y cuando se termine de descargar (o sea, en el evento JobDone), lo guardas en DirInternal
Habia pensado en lo segundo, esto fue lo que hice:

Priemor actualizo la base de datos, descargo de una base de datos online todos los registros y los guardo en una bd local. Luego, con este metodo recorro la base de datos local y guardo las imagenes que existen dentro de dicha db:
B4X:
Sub imagenesCargadas
'Con lo siguiente consultas la BD y guardas en la lista lstImagenesIconos el nombre de todas las imagenes de los comercios
lstImagenesIconos.Initialize
Dim UnaImagen As String
c=s.ExecQuery("SELECT imagen FROM comercios")
If c.RowCount>0 Then
    For i=0 To c.RowCount-1
        c.Position=i
        UnaImagen=c.GetString("imagen")
        lstImagenesIconos.Add(UnaImagen)
    Next
    End If
End Sub

Luego, de esa lista de imagenes, controlo si existen en dirassets, armo una lista con las que no existen en dirassets, y luego de esa lista controlo que imagenes existen en dirInternal:
B4X:
Sub imagenesPendientes
    Dim UnaImagen As String
    Dim UnaImagenProvisoria As String
    lstImagenesPendientesProvisorias.Initialize
    lstImagenesPendientes.Initialize
'Con el siguiente For-next recorres la lista de imágenes y compruebas cuáles de ellas las tienes ya descargadas y creas una nueva lista con las que te falten
For Numero = 0 To lstImagenesIconos.size - 1
     UnaImagen = lstImagenesIconos.Get(Numero) 'Recupera de la Lista de imágenes el nombre de cada una
     Log(UnaImagen&" que muestra?")
     'Comprueba si existe la imagen del botón y en caso contrario manda la guarda en la lista de imágenes faltantes

    'Comprueba si el archivo existe
     If Not(File.Exists(File.DirAssets,UnaImagen)) Then
         Log(UnaImagen & " - No existe")
         lstImagenesPendientesProvisorias.Add(UnaImagen)
     End If
Next

For i = 0 To lstImagenesPendientesProvisorias.Size - 1
    UnaImagenProvisoria = lstImagenesPendientesProvisorias.Get(i)
    If Not (File.Exists(File.DirInternal,UnaImagenProvisoria)) Then
        lstImagenesPendientes.Add(UnaImagenProvisoria)
    End If
Next
End Sub

Con las imagenes que no estan en dirAssets, ni en dirInternal, armo una nueva lista, esta lista contiene las imágenes a descargar.

Dentro del JobDone, que descarga la bd externa para actualizar las nuevas imagenes, llamo a un metodo para descargar las imagenes:
B4X:
Case "GetComercios"
                Dim ListaDatos As List
                ListaDatos = parser.NextArray 'returns a list with maps
                If ListaDatos.Size == 0 Then
                   'Algun mensaje.
                Else
                  s.BeginTransaction
                  s.ExecNonQuery("DELETE FROM comercios")
                  For i = 0 To ListaDatos.Size - 1
                       Dim Datos As Map
                       Datos = ListaDatos.Get(i)
                       s.ExecNonQuery2("INSERT INTO comercios VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)", Array As String(Datos.Get("id_comercio"), Datos.Get("id_rubro"), Datos.Get("comercio"), Datos.Get("imagen"), Datos.Get("descuento"), Datos.Get("direccion"), Datos.Get("latitud"), Datos.Get("longitud"), Datos.Get("telefono"), Datos.Get("correo_electronico"), Datos.Get("web"), Datos.Get("orden_listado"), Datos.Get("cantidad_ingresos")))
                  Next
                          'ToastMessageShow("Comercios actualizados", False)
                          imagenesCargadas
                          imagenesPendientes
                          descargarImagenes
                          s.TransactionSuccessful
                          s.EndTransaction
                End If
        End Select

El metodo que descarga la imagen:
B4X:
Sub descargarImagenes
    hilo.Initialize("hilo",Me)
    For Each imagenItem In lstImagenesPendientes
        hilo.Download("http://centrocomercialva.com.ar/imagenes/" & imagenItem)
        Log(imagenItem & " - Descargada")
        Dim out As OutputStream =File.OpenOutput(File.DirInternal, imagenItem, False)
        out.Close '<------ very important
    Next
End Sub

En otra pantalla, quiero listar los comercios y me da un erro de "Error loading bitmap". EL codigo para listarlos es el siguiente:
B4X:
Sub listarComercios
    c=s.ExecQuery("SELECT id_comercio,descuento,comercio,direccion,imagen FROM comercios WHERE comercios.id_rubro='" & Main.rubroElegido & "'")
    ListView1.Clear
    If c.RowCount>0 Then
        For i=0 To c.RowCount-1
            c.Position=i
            imagen=c.GetString("imagen")
            If( File.Exists(File.DirAssets,imagen)) Then
                ListView1.AddTwoLinesAndBitmap2(c.GetString("comercio"), c.GetString("descuento"),LoadBitmap(File.DirAssets,c.GetString("imagen")),c.GetString("id_comercio"))
            Else
                Log(imagen)
                ListView1.AddTwoLinesAndBitmap2(c.GetString("comercio"), c.GetString("descuento"),LoadBitmap(File.DirInternal,imagen),c.GetString("id_comercio"))
            End If
        Next
    End If
End Sub

Cuando cargo un nuevo comercio en la base de datos externas, al ejecutar por primera vez la app me aparece el log que puese para saber si detecta la imagen que no exite, y tambien aparece el log de "imagen descargada", que puse para saber si la descarga. Luego si la ejecuto de nuevo, la detecta como que no exite, pero no la descarga...
 
Top