How to dismiss dialog box before further processing? - java

I have an alertDialog that takes input for further processing. Because the processing can take a while, I want to close the alertDialog and display an image during the time it is doing the process method. The problem is that process() is called before the dialog is actually dismissed. So during that loading time the program basically 'hangs', displaying the alert dialog until process() finishes, after which the image is shown for a split second, defeating its purpose.
I have tried showing the image in the process() method, and tried doing dialog.dismiss() in a synchronized method, but the result stays the same.
alertDialogBuilder.setCancelable(true).setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
final String input = et.getText().toString();
dialog.dismiss(); //finish this first
process(input); //then do this
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();

You may use
alertDialogBuilder.setOnDismissListener(new
DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
//do work on dismiss of dialog
}
});
So,you can show the image in this section and start your process as well. Add a callback listener to process end and use the callback to make the image invisible when the process ends.

It should be as simple as
final String input = et.getText().toString();
dialog.dismiss();
// run in background
AsyncTask.execute(new Runnable() {
#Override
public void run() {
process(input);
}
});

Related

How to close a custom dialog automatically

I want to open a dialog. And dismiss automatically after a few seconds, the button in the dialog should also dismiss a dialog, whatever happens first. But I can't find the right way to close the dialog after time is up
I use the next custom dialog
private void okShowDialog(String title, String message){
vibrate();
final Dialog dialogo=new Dialog(Login.this);
dialogo.setContentView(R.layout.okdialog);
dialogo.setCancelable(false);
TextView errorTitle=dialogo.findViewById(R.id.lblTitleDialog);
errorTitle.setText(title);
TextView errorMessage=dialogo.findViewById(R.id.txtErrorDialog);
errorMessage.setText(message);
Button dialogButton = (Button) dialogo.findViewById(R.id.btnCont);
dialogButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
dialogo.show();
}
The dialog XML is very simple, it just shows a title, message, and button.
I've been through this for a couple of days and can't figure out how to solve it.
You can try to add Handler:
dialogo.show();
final Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
// Close dialog after 1000ms
dialogo.cancel();
}
}, 1000);
After 1000 ms (1 sec) Your dialog will be closed. I think that You don't have to check if a dialog was closed with a button and when You call again close on closed dialog You won't get any error but if I am not right just add a boolean variable to control if a dialog was closed by a button.
You could also use Kotlin Coroutine:
'build your dialog...'
dialog.setOnShowListener {
CoroutineScope(Dispatchers.Main).launch {
delay(length)
dialog.dismiss()
}
}
dialog.show()
Where 'length' is the time in milliseconds that you want the dialog to show for.

AlertDialog return boolean value

I am trying to include an AlertDialog builder within a method that prompts for a pin code and when the positive button is pressed, checks it against a database value and returns a true or false value to the method caller.
For example: Adding/editing/deleting a user task requires a pin code. I don't want to generate a different AlertDialog for all three (and more) of these actions. I want to wrap the following code within a TaskService class that I can call from any activity, and react based on the result from within that activity.
So TaskService.java would have:
public boolean isCorrectPin(View v){
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
final EditText editText = new EditText(context);
builder.setView(editText);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (editText.getText().toString()) == getPinCode(){
//return true
}
}
});
builder.show();
}
and OpenTaskAdapter.java would have:
public void onBindViewHolder(ViewHolder holder, int position){
holder.btnMarkAsComplete.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (service.isCorrectPin(v) {
//complete task
}
}
});
holder.btnDelete.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (service.isCorrectPin(v) {
//delete task
}
}
});
It's important to note that these two button listeners could be in totally different activities.
You can create your own method to generate dialog with listener:
public void isCorrectPin(Context context, String title, String message, String btnPositive, final DialogSingleButtonListener dialogSingleButtonListener) {
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle(title);
dialogBuilder.setMessage(message);
dialogBuilder.setPositiveButton(btnPositive, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (editText.getText().toString() == getPinCode()){
dialogSingleButtonListener.onButtonClicked(dialog);
}
}
});
AlertDialog dialog = dialogBuilder.create();
dialog.show();
}
And the listener class:
public interface DialogSingleButtonListener {
public abstract void onButtonClicked(DialogInterface dialog);
}
And use it like:
service.isCorrectPin(context, title, message, btnPositive
new DialogSingleButtonListener() {
#Override
public void onButtonClicked(DialogInterface dialog) {
//code here is only called if they entered a correct pin.
}
}
);
A dialog can't "return" a value in the way that it looks like you're expecting. A dialog can make changes to some other object, but you can't have a bit of code block on it and wait for the user to finish interacting with it.
Instead, you'll need to set up listeners for when the prompt dialog is dismissed or buttons or clicked, or whatever other event signals that you have what you need from it. Those listeners can then read the data gathered and set by the dialog.
this is how i'm doing :
public Boolean showAlert(String message)
{
action = false;
AlertDialog.Builder alertDialog = new AlertDialog.Builder(HAActivity.this);
// Setting Dialog Title
alertDialog.setTitle(getString(R.string.app_name));
// Setting Dialog Message
alertDialog.setMessage(message);
// Setting Icon to Dialog
// Setting Positive "Yes" Button
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
// Write your code here to invoke YES event
action = true;
}
});
// Setting Negative "NO" Button
alertDialog.setNegativeButton("Cancle", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to invoke NO event
action = false;
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
return action;
}
and calling function like this :
//activity in which you create function
if (Activity.showAlert("Do you really want to delete ??"))
{
//delete it anyway.
}

Android java AlertDialog error in AsyncTask

When I create AlertDialog in backgroud background thread AsyncTask, I get error. if I create AlertDialog outside of AsyncTask its working great. How I can fix that?
final ProgressDialog mDialog = new ProgressDialog(PageAndExercise.this);
mDialog.setMessage(getString(R.string.loading));
mDialog.setCancelable(false);
mDialog.show();
alertDialog2 = new AlertDialog.Builder(this);
AsyncTask.execute(new Runnable() {
#Override
public void run() {
mDialog.dismiss();
alertDialog2.setTitle(getString(R.string.tnxupload));
// Setting Dialog Message
alertDialog2.setMessage(getString(R.string.tnxupload2));
alertDialog2
.setCancelable(false)
.setPositiveButton("", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton(getString(R.string.tnxupload3), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
AlertDialog alertDialog = alertDialog2.create();
// show it
alertDialog2.show();
}
});
The error:
28928-31794/com.example.exampleE/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #5
Process: com.example.example, PID: 28928
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
You should look more into what AsyncTask does and why.
It is a convenience class to allow work to be done in the background. The doInBackground method allows long-running work to not block the UI thread.
However, if you want to display or perform tasks on the UI thread, you need to make sure those happen on the UI thread. For example, your line:
mDialog.dismiss();
should execute in onPreExecute because it impacts the UI. Likewise:
alertDialog2.show()
is trying to change the UI. This should be run in onPostExecute.
Fundamentally, though, building an AlertDialog is not a long running task at all. None of that needs to be in AsyncTask unless you have intentions to expand what happens prior to displaying the next dialog.
See this post here: http://blog.nikitaog.me/2014/10/11/android-looper-handler-handlerthread-i/
You can't interact with UI non from main-Thread.
The short solution here is:
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
// Call UI related methods.
}
});
I guess AsyncTask implement to your code is something like this:
final ProgressDialog mDialog = new ProgressDialog(this);
mDialog.setMessage("loading");
mDialog.setCancelable(false);
mDialog.show();
final AlertDialog.Builder alertDialog2 = new AlertDialog.Builder(this);
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
super.onPreExecute();
mDialog.dismiss();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
AlertDialog alertDialog = alertDialog2.create();
alertDialog2.setTitle("tnxupload");
alertDialog2.setMessage("tnxupload");
alertDialog2.setCancelable(false).setPositiveButton("", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
}).setNegativeButton("tnxupload3", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
alertDialog2.show();
}
#Override
protected Void doInBackground(Void... params) {
return null;
}
}.execute();

Android ProgressDialog not showing (blocked by code in other Thread)

Looking to similar questions everybody solve the problem of not appearing their Progress Dialog putting the intermediate code in a separate Thread.
My problem is that the mentioned solution is not working for me.
In my activity:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.dialog_ddbb_download_text)
.setPositiveButton(R.string.Accept, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// In this method I show the progress dialog
showProgressAndDownloadDDBB();
}
})
.setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
// Create the AlertDialog object and return it
builder.create().show();
Method in the activity:
private void showProgressAndDownloadDDBB() {
progressDialog = new ProgressDialog(mContext);
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.show();
// Here I call the Runnable to execute the code in other Thread and let the UI draw the Progress Dialog. If it wasn't called, the progress dialog does appear.
DDBB_Download_Manager ddbb_download_manager = new DDBB_Download_Manager(mContext, progressDialog);
ddbb_download_manager.run();
}
My runnable class, expected to run the intermediate code in a separate Thread:
public class DDBB_Download_Manager implements Runnable {
public DDBB_Download_Manager(Context context, ProgressDialog progressDialog) {
this.mContext = context;
this.mProgresDialog = progressDialog;
}
#Override
public void run() {
someCode()
Thread.sleep(3000);
// The GUI shows the accept Button clicked for 3 seconds (like it was freezed)
// Here I try to hide the Progress dialog after finishing the job, but it doesn't matter becasuse the progress dialog didn't even show up.
View rootView = ((Activity)mContext).getWindow().getDecorView().findViewById(android.R.id.content);
rootView.post(new Runnable() {
#Override
public void run() {
mProgresDialog.dismiss();
}
});
}
So the question is:
if I am executing the code between the Show and Dismiss methods of the Progress Dialog in a different Thread than the UI Thread, why is not the dialog showing up?
In fact it appears If I don't call the Runnable.
That is because you are running directly the dismiss() method from the runnable when you call ddbb_download_manager.run() where the progress dialog is cleared/done and if you are not calling it then the progress dialog will show due to that dismiss is on yet been called.
Make sure that you call ddbb_download_manager.run() when you want your progress dialog to be dismissed. don't call it directly after you show your progress dialog.
private void showProgressAndDownloadDDBB() {
progressDialog = new ProgressDialog(mContext);
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.show();
// Here I call the Runnable to execute the code in other Thread and let the UI draw the Progress Dialog. If it wasn't called, the progress dialog does appear.
DDBB_Download_Manager ddbb_download_manager = new DDBB_Download_Manager(mContext, progressDialog);
Handler handler = new Handler();
handler.postDelayed(ddbb_download_manager ,3*1000);
}

How to update AlertDialog content using showDialog(id)

i want to have in my application an alertdialog, that has its message updated everytime it is showed.
This is because the dialog box value depends on some values on the application.
Now i tried to use the showDialog method:
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
showDialog(RESULT_DIALOG);
return false;
}
But once the dialog is created, it doesn't change the message (i know that if the dialog is created, it use the started version).
My onCreateDialog method code is:
public Dialog onCreateDialog(int dialogId) {
AlertDialog dialog;
switch(dialogId) {
case RESULT_DIALOG:
// do the work to define the pause Dialog
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(localTv.getText())
.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
dialog = builder.create();
break;
default:
dialog = null;
}
return dialog;
}
There is a way to update the content of the AlertDialog.
Actually i create a new dialog box every time the onTouch event is called. But i'm not sure that it is the cleanest way to solve that problem.
Any idea?
Thanks :)
You have to use onPrepareDialog method:
#Override
protected void onPrepareDialog ( int id, Dialog dialog ) {
switch ( id ) {
case RESULT_DIALOG:
AlertDialog alertDialog = ( AlertDialog ) dialog;
alertDialog.setMessage( localTv.getText() );
break;
}
super.onPrepareDialog( id, dialog );
}
From http://developer.android.com/guide/topics/ui/dialogs.html :
Before the dialog is displayed, Android also calls the optional
callback method onPrepareDialog(int, Dialog). Define this method if
you want to change any properties of the dialog each time it is
opened. This method is called every time a dialog is opened, whereas
onCreateDialog(int) is only called the very first time a dialog is
opened. If you don't define onPrepareDialog(), then the dialog will
remain the same as it was the previous time it was opened. This method
is also passed the dialog's ID, along with the Dialog object you
created in onCreateDialog().
You can always change the dialog using onPrepareDialog or you can remove the dialog (so it will always pass through onCreateDialog) setting the onDismiss (dialog.setOnDismiss) to remove the dialog id (removeDialog(id)).

Categories

Resources