alternative - Android Back Button y Progress Dialog
progress dialog android deprecated (9)
Tengo una AsyncTask que muestra un progressDialog mientras trabaja (llama a runOnUiThread desde doInBackground para mostrar el diálogo de progreso).
Mientras está en funcionamiento, quiero permitir el uso del botón Atrás para cancelar la operación; alguien más ha tenido este problema: el botón ATRÁS no funciona, mientras progressDialog se está ejecutando
Por alguna razón, no puedo responder a ese hilo, por lo tanto, ¿tengo que empezar otro? (Otra pregunta para otro día)
Tuve la misma idea que Sandy pero este código nunca se invoca mientras se muestra progressDialog , ¿por qué? Lo he implementado dentro de mi clase de actividad principal, ¿el progressDialog elimina el enfoque de primer plano de mi clase temporalmente?
Acabo de encontrar una solución perfecta y más simple para este problema. Hay un método en ProgressDialog
para configurar KeyListener.
progressDialog.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_BACK && !event.isCanceled()) {
if(progressDialog.isShowing()) {
//your logic here for back button pressed event
}
return true;
}
return false;
}
});
Funciona bien con setCancelable(false)
. También estoy buscando event.isCanceled()
, porque sin eso obtuve dos eventos. Probé esto en un dispositivo Lollipop con y sin las teclas de Hardware.
Aquí está mi solución a esto. El problema de PD solo ocurre cuando la aplicación sale en el botón Atrás (generalmente cuando el usuario lo presiona repetidamente, y solo algunas veces (no todas las veces) se llama al PD cuando la aplicación ya se destruyó. Descartar el PD onDestroy
no funciona para algunos razón y cuando lo he probado, cada vez que presiona el botón Atrás cerraría la aplicación aunque canGoBack()
se configuró en verdadero. En cambio, goBack
la PD en goBack
que es el evento que causa la colisión en primer lugar, y lo hago justo antes de finish()
. Si la aplicación sale en goBack normalmente no hay problema en primer lugar.
Por cierto, ''diferencia'' tiene como objetivo permitir al usuario salir de la aplicación con un doble clic rápido (400 MS entre dos clics) en lugar de ir de página en página.
Espero que ayude a alguien ...
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
difference = System.currentTimeMillis() - startTime;
if (wView.canGoBack() && difference > 400) {
wView.goBack();
} else {
dismissProgressDialog();
finish();
}
startTime = System.currentTimeMillis();
return true;
}
}
return super.onKeyDown(keyCode, event);
}
private void dismissProgressDialog() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
Bueno, tuve el mismo problema. El método más simple que funcionó para mí es el uso de progressDialog.setCancelable(true)
. Esto declara si el diálogo es cancelable presionando la tecla de retroceso. Pruébalo y avísame si funciona para ti o no. Buena suerte
Es muy simple copiar el código a continuación y pegarlo dentro de la tarea Async.
Diálogo ProgressDialog;
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(MainActivity.this) {
@Override
public void onBackPressed() {
dialog.cancel();
dialog.dismiss();
}
};
// dialog.setTitle("file is..");//its optional If u want set title in progress
// bar
dialog.setMessage("Loading file....");
dialog.setCancelable(false);
dialog.show();
}
Esto se puede lograr con el siguiente fragmento de código:
progress.setCancelable(true);
progress.setCanceledOnTouchOutside(false);
el progreso es el objeto ProgressDialog ...
Esto permitirá que el botón Atrás cierre el diálogo, pero previene que cualquier entrada táctil lo haga ...
Por favor, siga esto, muestra que el botón Cancelar solo asíncrona y el final lo llamará haciendo clic en el botón cancelar
protected void onPreExecute() {
dialogx.setMessage("Loading... Please Wait...");
dialogx.setCancelable(false);
dialogx.setButton(DialogInterface.BUTTON_NEGATIVE,
"Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialogx.dismiss();
GetDataTask.this.cancel(true);
finish();
}
});
dialogx.show();
}
Tratar el botón Atrás como una cancelación no es la forma correcta.
La cancelación también ocurre cuando un usuario toca la pantalla fuera del cuadro de diálogo. ¿Quieres diferenciar esas dos acciones, no?
El enfoque correcto sería extender la clase ProgressDialog y anular el método onBackPressed.
private class SubProgressDialog extends ProgressDialog {
public SubProgressDialog(Context context) {
super(context);
}
@Override
public void onBackPressed() {
/** dismiss the progress bar and clean up here **/
}
}
public void displayProgressBar(){
progressBar = new SubProgressDialog(this);
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressBar.setCancelable(false);
progressBar.setMessage(getString(R.string.authorizing));
progressBar.show();
new Thread(new Runnable() {
public void run() {
}
}).start();
}
Observe el setCancelable (falso), nuevamente enfatizando que el botón Atrás es diferente a una cancelación simple.
También esto ignorará de forma efectiva cualquier otra entrada táctil del usuario.
javano ... Probé tu escenario usando técnicas estándar, asyncTask y ProgressDialog. En mi prueba, cuando el progresoDialog se muestra y respondo, el progresodialog se descarta y el hilo de fondo continúa ejecutándose. No sé por qué necesitas llamar a runOnUiThread.
ASI QUE:
muestra el progresoDialog en onPreExecute coloca la tarea larga en doInBackground descarta el progressDialog en onPostExecute pasa los parámetros de entrada a tu tarea de larga ejecución como en:
new MyAsynch().execute(password,inString);
cancel () el asynchTask y progressDialog en onPause
protected void onPause() {
super.onPause();
if (asynch != null) {asynch.cancel(true);}
if (progress != null){progress.cancel();}
}
JAL
Tengo un código here .
En primer lugar, debe mostrar su cuadro de diálogo desde OnPreExecute
, ocultarlo en OnPostExecute
y, si es necesario, modificarlo publicando el progreso. (ver here )
Ahora a su pregunta: ProgressDialog.show()
puede tomar un OnCancelListener
como argumento. Debe proporcionar uno que llame a cancel()
en la instancia de diálogo de progreso.
ejemplo:
@Override
protected void onPreExecute(){
_progressDialog = ProgressDialog.show(
YourActivity.this,
"Title",
"Message",
true,
true,
new DialogInterface.OnCancelListener(){
@Override
public void onCancel(DialogInterface dialog) {
YourTask.this.cancel(true);
finish();
}
}
);
}
donde _progressDialog
es un miembro de ProgressDialog
de YourTask
.
Esta clase quedó obsoleta en el nivel 26 de la API. ProgressDialog es un cuadro de diálogo modal, que evita que el usuario interactúe con la aplicación. En lugar de utilizar esta clase, debe usar un indicador de progreso como ProgressBar, que puede integrarse en la IU de su aplicación. Alternativamente, puede usar una notificación para informar al usuario del progreso de la tarea. LINK