none
Implementar barra de progreso en descarga de varios archivos. RRS feed

  • Pregunta

  • Buenas noches, de antemano les agradezco cualquier apoyo que me puedan brindar.

    Tengo el siguiente problema, estoy intentando hacer auna App para android con Xamarin Forms, y una de las cosas de lo que quiero hacer es descargar archivos de un servidor ftp. 

    Buscando en los web he logrado poder descargar un archivo, pero quiero poder descargar varios archivos y agregar una barra de progreso pero por mas que le he buscado no encuentro la menera de poder hacer lo que quiero.

    A continuación les agrego la parte de codigo que llevo.

    en mi proyecto compartido

    *.- creo mis objetos 

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="ProyAppPortatil.ActualizaArticulos"
                 Title="Actualiza Articulos">
        <ContentPage.Content>
            <StackLayout VerticalOptions="Center">
                <Button Text="Descargar Nuevos Articulos" x:Name="btnDescargaArticulos" Clicked="BtnDescargaArticulos_Clicked" HorizontalOptions="FillAndExpand"
                        TextColor="Blue"/>
                <Button Text="Insertar Articulos Descargados" x:Name="btnInsertarArticulos" Clicked="BtnInsertarArticulos_Clicked" HorizontalOptions="FillAndExpand"
                        TextColor="Blue"/>
                <Label Text="" x:Name="lbtextoProgreso" TextColor="Black" HorizontalOptions="Center"/>
                <ProgressBar x:Name="barraProgreso" HorizontalOptions="FillAndExpand" ProgressColor="Orange" Progress="0.0"/>
            </StackLayout>
        </ContentPage.Content>
    </ContentPage>

    *.- clase de los objetos

    using System;
    using System.IO;
    using System.Linq;
    using System.Net;

    using Xamarin.Forms;
    using Xamarin.Forms.PlatformConfiguration;
    using Xamarin.Forms.Xaml;

    namespace ProyAppPortatil
    {
        //[XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class ActualizaArticulos : ContentPage
    {               
            IDownloader downloader = DependencyService.Get<IDownloader>();        
            public ActualizaArticulos ()
    {
    InitializeComponent ();
                downloader.OnFileDownloaded += OnFileDownloaded;           
            }
            
            private void OnFileDownloaded(object sender, DownloadEventArgs e)
            {
                if (e.FileSaved)
                {
                    lbtextoProgreso.Text = "¡Descarga finalizada!...";
                }            
            }

            private void BtnDescargaArticulos_Clicked(object sender, EventArgs e)
            {
                lbtextoProgreso.Text = "Descargando catalogo de articulo...";

                downloader.DownloadFile("ftp://192.168.1.3/T_XmlTallas.xml", "Xml_Catalogos", "usuarioftp", "passftp");

                downloader.DownloadFile("ftp://192.168.1.3/C_XmlColores.xml", "Xml_Catalogos", "usuarioftp", "passftp");                                                                     

                downloader.DownloadFile("ftp://192.168.1.3/E_XmlEstilos.xml", "Xml_Catalogos", "usuarioftp", "passftp");

                downloader.DownloadFile("ftp://192.168.1.3/A_XmlArticulos.xml", "Xml_Catalogos", "usuarioftp", "passftp");
            }

            private void BtnInsertarArticulos_Clicked(object sender, EventArgs e)
            {

            }       
        }
    }


    *.- creo mi interfaz

    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Text;

    namespace ProyAppPortatil
    {
        public interface IDownloader
        {     
            void DownloadFile(string url, string folder, string ftpUser, string passFtp);
            event EventHandler<DownloadEventArgs> OnFileDownloaded;
        }

        public class DownloadEventArgs : EventArgs
        {
            public bool FileSaved = false;
            public DownloadEventArgs(bool fileSaved)
            {
                FileSaved = fileSaved;
            }       
        }         
    }

    *.- creo una clase dentro del proyecto android para hacerla descarga

                

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Text;

    using Android.App;
    using Android.Content;
    using Android.OS;
    using Android.Runtime;
    using Android.Views;
    using Android.Widget;
    using ProyAppPortatil.Droid;
    using Xamarin.Forms;

    [assembly: Dependency(typeof(AndroidDownloader))]
    namespace ProyAppPortatil.Droid
    {
        public class AndroidDownloader : IDownloader    
        {               
            public event EventHandler<DownloadEventArgs> OnFileDownloaded;
            public event EventHandler<DownloadDataCompletedEventArgs> OnFilePogressDownload;

            public void DownloadFile(string url, string folder, string ftpUser, string passFtp)
            {
                string pathToNewFolder = Path.Combine(Android.App.Application.Context.GetExternalFilesDir(null).ToString(), folder);
                Directory.CreateDirectory(pathToNewFolder);

                try
                {
                    WebClient webClient = new WebClient();
                    webClient.Credentials = new NetworkCredential(ftpUser, passFtp);
                    webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
                    string pathToNewFile = Path.Combine(pathToNewFolder, Path.GetFileName(url));
                    webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
                    webClient.DownloadFileAsync(new Uri(url), pathToNewFile);
                }
                catch (Exception)
                {
                    if (OnFileDownloaded != null)
                        OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
                }
            }

            private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
            {

            }        

            private void Completed(object sender, AsyncCompletedEventArgs e)
            {
                OnFileDownloaded.Invoke(this, new DownloadEventArgs(true));
                //if (e.Error != null)
                //{
                //    if (OnFileDownloaded != null)
                //        OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
                //}
                //else
                //{
                //    if (OnFileDownloaded != null)
                //        OnFileDownloaded.Invoke(this, new DownloadEventArgs(true));
                //}
            }
        }
    }

    Espero pueda darme alguna idea, muchas gracias, saludos.

    viernes, 13 de diciembre de 2019 2:01

Respuestas

  • si lo sabes, ya lo estas realizando con el

    public event EventHandler<DownloadEventArgs> OnFileDownloaded;

    cuando usas

    if (OnFileDownloaded != null)
        OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
             

    tiene que lanzar el evento, pero ademas debes subscribirte a este desde la UI, el tema es que no lo expones 

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta delfino morales viernes, 13 de diciembre de 2019 20:16
    viernes, 13 de diciembre de 2019 18:56

Todas las respuestas

  • hola

    El tema que observo es que no le haces llegar la info desde

      webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);

     a la UI para que represente el avance

    quizas la clase

       AndroidDownloader

    la cual se expone por la interfaz

    deberias exponer un evento al cual la UI xaml pueda adjuntarse para recibir la informacion de progreso del WebClient, o sea la interfaz deberia tambien definir este evento

    Veo la linea

    public event EventHandler<DownloadDataCompletedEventArgs> OnFilePogressDownload;

    pero porque no lanzas nada en

            private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
            {
                 //aqui falta codigo
            }  

    y ademas debes exponerla en la interface para adjuntarte en xaml

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    viernes, 13 de diciembre de 2019 14:25
  • Hola Leandro, gracias por responder.

    Precisamente en este punto no se como lanzar o llamar el evento.

    private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
            {
                 //no se como hacer el llamado
            }  

    Saludos.

    viernes, 13 de diciembre de 2019 17:55
  • si lo sabes, ya lo estas realizando con el

    public event EventHandler<DownloadEventArgs> OnFileDownloaded;

    cuando usas

    if (OnFileDownloaded != null)
        OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
             

    tiene que lanzar el evento, pero ademas debes subscribirte a este desde la UI, el tema es que no lo expones 

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta delfino morales viernes, 13 de diciembre de 2019 20:16
    viernes, 13 de diciembre de 2019 18:56
  • Muchas gracias Leandro, ya pude resolverlo.

    Una ultima consulta, el ProgressBar comienza a cargar pero llega un punto en el que se detiene y no se llena completamente, que me faltaria por hacer?

    Saludos.

    viernes, 13 de diciembre de 2019 20:18
  • hola

    >>el ProgressBar comienza a cargar pero llega un punto en el que se detiene y no se llena completamente, que me faltaria por hacer?

    Pero es un problema del progress o del WebClient cuando informa el progreso?

    puede que el calculo del valor Maximo que indicas en el progress no sea el correcto comparado con el peso de los archivos, por eso el avance no coincide

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    viernes, 13 de diciembre de 2019 20:30
  • si tienes razón, creo que ya le entendí.

    nuevamente muchas gracias, saludos desde tijuana baja california, mexico.

    viernes, 13 de diciembre de 2019 20:33