Estoy tratando de escribir una aplicación simple que se actualice. Para esto necesito una función simple que pueda descargar un archivo y mostrar el progreso actual en a ProgressDialog
. Sé cómo hacerlo ProgressDialog
, pero no estoy seguro de cómo mostrar el progreso actual y cómo descargar el archivo en primer lugar.
java
android
download
android-asynctask
Tom Leese
fuente
fuente
Respuestas:
Hay muchas formas de descargar archivos. A continuación publicaré las formas más comunes; depende de usted decidir qué método es mejor para su aplicación.
1. Use
AsyncTask
y muestre el progreso de la descarga en un cuadro de diálogoEste método le permitirá ejecutar algunos procesos en segundo plano y actualizar la IU al mismo tiempo (en este caso, actualizaremos una barra de progreso).
Importaciones:
Este es un código de ejemplo:
El
AsyncTask
se verá así:El método anterior (
doInBackground
) se ejecuta siempre en un hilo de fondo. No deberías hacer ninguna tarea de IU allí. Por otro lado, elonProgressUpdate
yonPreExecute
ejecutar en el hilo de la interfaz de usuario, por lo que puede cambiar la barra de progreso:Para que esto se ejecute, necesita el permiso WAKE_LOCK.
2. Descargar del servicio
La gran pregunta aquí es: ¿cómo actualizo mi actividad desde un servicio? . En el siguiente ejemplo, vamos a utilizar dos clases que quizás no conozcas:
ResultReceiver
yIntentService
.ResultReceiver
es el que nos permitirá actualizar nuestro hilo desde un servicio;IntentService
es una subclase de laService
cual se genera un hilo para hacer un trabajo de fondo desde allí (debe saber que seService
ejecuta realmente en el mismo hilo de su aplicación; cuando extiendeService
, debe generar manualmente nuevos subprocesos para ejecutar operaciones de bloqueo de la CPU).El servicio de descarga puede verse así:
Agregue el servicio a su manifiesto:
Y la actividad se verá así:
Aquí es donde
ResultReceiver
viene a jugar:2.1 Usar la biblioteca Groundy
Groundy es una biblioteca que básicamente te ayuda a ejecutar fragmentos de código en un servicio en segundo plano, y se basa en el
ResultReceiver
concepto que se muestra arriba. Esta biblioteca está en desuso en este momento. Así es como el todo se vería código:La actividad donde está mostrando el diálogo ...
Una
GroundyTask
implementación utilizada por Groundy para descargar el archivo y mostrar el progreso:Y solo agregue esto al manifiesto:
No podría ser más fácil, creo. Simplemente tome el último frasco de Github y estará listo para comenzar. Manten eso en mente el propósito principal de Groundy es hacer llamadas a aplicaciones REST externas en un servicio en segundo plano y publicar resultados en la interfaz de usuario con facilidad. Si está haciendo algo así en su aplicación, podría ser realmente útil.
2.2 Uso https://github.com/koush/ion
3. Use
DownloadManager
class (GingerBread
y más reciente solamente)GingerBread trajo una nueva característica,
DownloadManager
que le permite descargar archivos fácilmente y delegar el arduo trabajo de manejar hilos, transmisiones, etc. al sistema.Primero, veamos un método de utilidad:
El nombre del método lo explica todo. Una vez que esté seguro de que
DownloadManager
está disponible, puede hacer algo como esto:El progreso de la descarga se mostrará en la barra de notificaciones.
Pensamientos finales
El primer y segundo método son solo la punta del iceberg. Hay muchas cosas que debes tener en cuenta si quieres que tu aplicación sea robusta. Aquí hay una breve lista:
INTERNET
yWRITE_EXTERNAL_STORAGE
); tambiénACCESS_NETWORK_STATE
si quieres consultar la disponibilidad de internet.A menos que necesite un control detallado del proceso de descarga, considere usar
DownloadManager
(3) porque ya maneja la mayoría de los elementos enumerados anteriormente.Pero también considere que sus necesidades pueden cambiar. Por ejemplo,
DownloadManager
no responde el almacenamiento en caché . Descargará ciegamente el mismo archivo grande varias veces. No hay una manera fácil de arreglarlo después del hecho. Donde si comienzas con un básicoHttpURLConnection
(1, 2), entonces todo lo que necesitas es agregar unHttpResponseCache
. Por lo tanto, el esfuerzo inicial de aprender las herramientas básicas y estándar puede ser una buena inversión.fuente
close()
las secuencias (input
youtput
) enfinally
lugar detry
, de lo contrario, si se produce alguna excepción antesclose()
, tiene secuencias no cerradas dando vueltas.sdcard/
useEnvironment.getExternalStorageDirectory()
en su lugar.¡No olvide agregar permisos a su archivo de manifiesto si va a descargar cosas de Internet!
fuente
Si el código anterior funcionará Pero si usted está actualizando su
progressbar
enonProgressUpdate
deAsynctask
y pulse el botón Atrás o terminar su actividadAsyncTask
pierde su pista con su interfaz de usuario .Y cuando vuelva a su actividad, incluso si la descarga se está ejecutando en segundo plano verá Sin actualización en la barra de progreso. Entonces,OnResume()
intente ejecutar un hilo comorunOnUIThread
con una tarea de temporizador que actualiza su urprogressbar
con valores que se actualizan desde elAsyncTask
fondo en ejecución.No olvides destruir el hilo cuando tu actividad no sea visible.
fuente
Te recomiendo que uses mi Proyecto Netroid , está basado en Volley . Le he agregado algunas características, como la devolución de llamada de eventos múltiples, la gestión de descarga de archivos. Esto podría ser de alguna ayuda.
fuente
SSLSocketFactory
adición,HostnameVerifier
no es posible y necesito dicho verificador. Planteó un problema al respecto.He modificado la
AsyncTask
clase para manejar la creaciónprogressDialog
en el mismo contexto. Creo que el siguiente código será más reutilizable. (se puede invocar desde cualquier actividad, solo pasa contexto, archivo de destino, mensaje de diálogo)fuente
No olvide reemplazar "/ sdcard ..." por un nuevo archivo ("/ mnt / sdcard / ...") de lo contrario obtendrá una FileNotFoundException
fuente
Environment.getExternalStorageDirectory().getAbsolutePath()
para obtener un camino a sdcard. Además, no olvide comprobar si el almacenamiento externo está montado -Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
( Mannaz )Encontré esta publicación de blog muy útil, está usando loopJ para descargar el archivo, solo tiene una función Simple, será útil para algunos chicos nuevos de Android.
fuente
Mientras comenzaba a aprender el desarrollo de Android, aprendí que ese
ProgressDialog
es el camino a seguir. Existe elsetProgress
métodoProgressDialog
que se puede invocar para actualizar el nivel de progreso a medida que se descarga el archivo.Lo mejor que he visto en muchas aplicaciones es que personalizan los atributos de este diálogo de progreso para darle una mejor apariencia al diálogo de progreso que la versión estándar. Es bueno mantener al usuario comprometido con alguna animación de rana, elefante o lindos gatos / cachorros. Cualquier animación en el cuadro de diálogo de progreso atrae a los usuarios y no tienen ganas de esperar mucho tiempo.
fuente
Mi consejo personal es usar el Diálogo de progreso y construir antes de la ejecución, o iniciar en
OnPreExecute()
, publicar el progreso a menudo si usa el estilo horizontal de la barra de progreso del diálogo de progreso. La parte restante es optimizar el algoritmo dedoInBackground
.fuente
Use la biblioteca de Android Query, realmente genial. Puede cambiarla para usarla
ProgressDialog
como ve en otros ejemplos, esta mostrará la vista de progreso de su diseño y la ocultará después de completarla.fuente
Estoy agregando otra respuesta para otra solución que estoy usando ahora porque Android Query es muy grande y no se mantiene para mantenerse saludable. Así que me mudé a esta https://github.com/amitshekhariitbhu/Fast-Android-Networking .
fuente
Permisos
Usando HttpURLConnection
fuente
Puede observar el progreso del administrador de descargas utilizando LiveData y corutinas, vea la esencia a continuación
https://gist.github.com/FhdAlotaibi/678eb1f4fa94475daf74ac491874fc0e
fuente
Importante
AsyncTask está en desuso en Android 11.
Para obtener más información, consulte las siguientes publicaciones
Probablemente debería pasar al Marco de concorency como lo sugiere google
fuente
Podemos usar la rutina y el administrador de trabajo para descargar archivos en kotlin.
Agregar una dependencia en build.gradle
Clase WorkManager
Comience a descargar a través del administrador de trabajo en la clase de actividad
fuente